home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume8 / se / part05 < prev    next >
Encoding:
Internet Message Format  |  1987-01-25  |  58.3 KB

  1. Subject:  v08i005:  Georgia Tech 'se' Screen Editor
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: emoryu1!arnold (Arnold D. Robbins)
  6. Mod.sources: Volume 8, Issue 5
  7. Archive-name: se/Part05
  8.  
  9.  
  10. Here is the second release of the Georgia Tech Screen Editor, 'se'.
  11. There were enough changes that a whole new posting is warranted.
  12.  
  13. Major Changes:
  14.     All Georgia Tech specific stuff removed.
  15.     It understands window size changes on 4.3BSD and ATT Unix PC/3B1
  16.     Support for the shared library on the ATT Unix PC/3B1
  17.     Considerable source code reorganization in certain files.
  18.  
  19. Enjoy,
  20.  
  21. Arnold Robbins
  22.  
  23. #! /bin/sh
  24. # This is a shell archive, meaning:
  25. # 1. Remove everything above the #! /bin/sh line.
  26. # 2. Save the resulting text in a file.
  27. # 3. Execute the file with /bin/sh (not csh) to create the files:
  28. #    term.c
  29. #    libchangetty
  30. #    pat
  31. export PATH; PATH=/bin:$PATH
  32. echo shar: extracting "'term.c'" '(37533 characters)'
  33. if test -f 'term.c'
  34. then
  35.     echo shar: will not over-write existing file "'term.c'"
  36. else
  37. cat << \SHAR_EOF > 'term.c'
  38. #ifndef lint
  39. static char RCSid[] = "$Header: term.c,v 1.7 86/11/12 11:37:30 arnold Exp $";
  40. #endif
  41.  
  42. /*
  43.  * $Log:    term.c,v $
  44.  * Revision 1.7  86/11/12  11:37:30  arnold
  45.  * Fixed winsize() to verify that cols and rows not 0 before assigning
  46.  * them to Nrows and Ncols.
  47.  * 
  48.  * Revision 1.6  86/10/14  11:10:36  arnold
  49.  * Reorganization of window handling stuff. Added (untested) code for sun.
  50.  * 
  51.  * Revision 1.5  86/10/07  14:50:48  arnold
  52.  * Changed setterm to set_term, to avoid Unix/PC shared library conflict.
  53.  * Fixed winsize() to set Nrows and Ncols on first call, as well.
  54.  * 
  55.  * Revision 1.4  86/09/19  12:15:28  arnold
  56.  * Fixes to BSD windowing for real 4.3, from BRL.
  57.  * 
  58.  * Revision 1.3  86/07/17  17:23:19  arnold
  59.  * Massive reorganization and cleaning up. Terminal initialization
  60.  * stuff moved here, and homogenized.
  61.  * 
  62.  * Revision 1.2  86/07/14  17:19:33  arnold
  63.  * Added code that notices whether or not the window we are runnng in has
  64.  * changed sizes. It definitely works on the Unix PC, and should work on
  65.  * BRL Unix and 4.3 BSD.
  66.  * 
  67.  * Revision 1.1  86/05/06  13:38:53  osadr
  68.  * Initial revision
  69.  * 
  70.  * 
  71.  */
  72.  
  73. /*
  74. ** term.c
  75. **
  76. ** provide terminal functions for se
  77. **
  78. ** If HARD_TERMS is *not* defined, which is the default, se will
  79. ** use the termlib library, which provides terminal independant operations.
  80. ** This makes se both smaller, and more flexible.
  81. **
  82. ** If HARD_TERMS is defined, then se will use the original code, which
  83. ** had terminal types hard-wired into the code.  This would be useful for
  84. ** a system which does not have the termlib library.
  85. **
  86. ** On System V systems, we have two possibilities.  Release 1 did not have
  87. ** the terminfo package, so we assume that if it is Release 1, someone will
  88. ** have ported the BSD termlib library.  If it is Release 2, then the new
  89. ** terminfo package is there, and we wil use it.
  90. **
  91. ** This file is large. It is organized as follows.
  92. **
  93. ** Routines that do not care whether or not HARD_TERMS is defined.
  94. ** Routines that are only if HARD_TERMS is NOT defined. These contain:
  95. **    BSD/termlib routines
  96. **    System V/terminfo routines
  97. **    Routines idenpendant of BSD/System V
  98. ** Routines that are only if HARD_TERMS is defined.
  99. ** Routines that have regular and conditonal code mixed.
  100. */
  101.  
  102. #include "se.h"
  103. #include "extern.h"
  104.  
  105. /* outc -- write a character to the terminal */
  106.  
  107. int outc (c)
  108. char c;
  109. {
  110.     twrite (1, &c, 1);
  111. }
  112.  
  113. #ifndef HARD_TERMS
  114. #if defined (BSD) || !defined (S5R2)
  115. /*
  116.  * code for using BSD termlib -- getting capabilities, and writing them out.
  117.  */
  118.  
  119. /* capabilities from termcap */
  120.  
  121. static int AM;        /* automatic margins, i.e. wraps at column 80 */
  122.  
  123. static char *VS;    /* visual start -- e.g. clear status line */
  124. static char *VE;    /* visual end -- e.g. restore status line */
  125. static char *TI;    /* terminal init -- whatever needed for screen ops */
  126. static char *TE;    /* terminal ops end */
  127. static char *CM;    /* cursor motion, used by tgoto() */
  128. static char *CE;    /* clear to end of line */
  129. static char *DL;    /* hardware delete line */
  130. static char *AL;    /* hardware add (insert) line */
  131. static char *CL;    /* clear screen */
  132.  
  133. extern char PC;        /* Pad character, usually '\0' */
  134.  
  135. static char *pcstr;
  136. extern char *tgoto (), *tgetstr ();    /* termlib routines */
  137.  
  138. static char caps[128];        /* space for decoded capability strings */
  139. static char *addr_caps;        /* address of caps for relocation */
  140.  
  141. #define TERMBUFSIZ    1024+1
  142. static char termbuf[TERMBUFSIZ];
  143.  
  144. /* getdescrip --- get descriptions out of termcap entry */
  145.  
  146. static getdescrip ()
  147. {
  148.     int i;
  149.     static struct _table {
  150.         char *name;
  151.         char **ptr_to_cap;
  152.         } table[] = {
  153.             "vs",    & VS,
  154.             "ve",    & VE,
  155.             "ti",    & TI,
  156.             "te",    & TE,
  157.             "cm",    & CM,
  158.             "ce",    & CE,
  159.             "dl",    & DL,
  160.             "al",    & AL,
  161.             "cl",    & CL,
  162.             "pc",    & pcstr,
  163.             NULL,    NULL
  164.             };
  165.  
  166.     AM = tgetflag ("am");        /* only boolean se needs */
  167.  
  168.     /* get string values */
  169.  
  170.     for (i = 0; table[i].name != NULL; i++)
  171.         *(table[i].ptr_to_cap) = tgetstr (table[i].name, & addr_caps);
  172. }
  173.  
  174. /* setcaps -- get the capabilities from termcap file into termbuf */
  175.  
  176. static setcaps (term)
  177. char *term;
  178. {
  179.     switch (tgetent (termbuf, term)) {
  180.     case -1:
  181.         error (NO, "se: couldn't open termcap file.");
  182.  
  183.     case 0:
  184.         error (NO, "se: no termcap entry for %s terminals.", term);
  185.  
  186.     case 1:
  187.         addr_caps = caps;
  188.         getdescrip ();        /* get terminal description */
  189.         Nrows = tgetnum ("li");
  190.         Ncols = tgetnum ("co");
  191.         break;
  192.  
  193.     default:
  194.         error (YES, "in setcaps: can't happen.\n");
  195.     }
  196.  
  197.     return (OK);
  198. }
  199.  
  200. #else
  201.  
  202. /* use the new terminfo package */
  203. /*
  204.  * Do NOT include <curses.h>, since it redefines
  205.  * USG, ERR, and OK, to values inconsistent with what
  206.  * we use.
  207.  */
  208.  
  209. /* fix a problem in /usr/include/term.h */
  210. #include <termio.h>
  211. typedef struct termio SGTTY;
  212.  
  213. #include <term.h>    /* should be all we really need */
  214.  
  215. #define AM    auto_right_margin
  216. #define TI    enter_ca_mode
  217. #define TE    exit_ca_mode
  218. #define VS    cursor_visible
  219. #define VE    cursor_normal
  220. #define CL    clear_screen
  221. #define CE    clr_eol
  222. #define DL    delete_line
  223. #define AL    insert_line
  224.  
  225. /* setcaps -- get the capabilities from the terminfo database */
  226.  
  227. static setcaps (term)
  228. char *term;
  229. {
  230.     int ret = 0;
  231.  
  232.     setupterm (term, 1, & ret);
  233.     if (ret != 1)
  234.         return (ERR);
  235.     Nrows = lines;
  236.     Ncols = columns;
  237.  
  238.     return (OK);
  239. }
  240. #endif
  241.  
  242. /* t_init -- put out terminal initialization string */
  243.  
  244. t_init ()
  245. {
  246.     if (VS)
  247.         tputs (VS, 1, outc);
  248.     if (TI)
  249.         tputs (TI, 1, outc);    /* terminal initializations */
  250. }
  251.  
  252. /* t_exit -- put out strings to turn off whatever modes we had turned on */
  253.  
  254. t_exit ()
  255. {
  256.     /* terminal exiting strings */
  257.     if (TE)
  258.         tputs (TE, 1, outc);
  259.     if (VE)
  260.         tputs (VE, 1, outc);
  261.     tflush ();    /* force it out */
  262. }
  263.  
  264. /* winsize --- get the size of the window from the windowing system */
  265. /*        also arrange to catch the windowing signal */
  266.  
  267. #include <signal.h>
  268.  
  269. #ifdef SIGWIND            /* UNIX PC */
  270. #include <sys/font.h>
  271. #include <sys/window.h>
  272. #define WINSIG        SIGWIND
  273. #define WINIOCTL    WIOCGETD
  274. #define WINSTRUCT    uwdata
  275. #define COLS        (w.uw_width / w.uw_hs)
  276. #define ROWS        (w.uw_height / w.uw_vs)
  277. #endif
  278.  
  279. #ifdef SIGWINCH            /* 4.3 BSD and/or Sun 3.x */
  280.  
  281. #define WINSIG        SIGWINCH
  282.  
  283. #ifdef sun
  284. #undef NEWLINE        /* shouldn't hurt; these are in sun include files */
  285. #undef TAB
  286. #include <sys/types.h>
  287. #include <sys/ioctl.h>
  288. #include <sys/tty.h>
  289. #define WINIOCTL TIOCGSIZE
  290. #define WINSTRUCT ttysize
  291. #define COLS w.ts_cols
  292. #define ROWS w.ts_lines
  293.  
  294. #else
  295.  
  296. #include <sys/ioctl.h>
  297. #define WINIOCTL    TIOCGWINSZ
  298. #define WINSTRUCT    winsize
  299. #define COLS w.ws_col
  300. #define ROWS w.ws_row
  301. #endif
  302. #endif
  303.  
  304. static struct WINSTRUCT w;
  305.  
  306. winsize ()
  307. {
  308. #if defined(SIGWIND) || defined(SIGWINCH)
  309.     static int first = 1;
  310.     static char savestatus[MAXCOLS];
  311.     int row, oldstatus = Nrows - 1;
  312.     int cols, rows;
  313.  
  314.     signal (WINSIG, winsize);
  315.  
  316.     if (ioctl (0, WINIOCTL, (char *) & w) != -1)
  317.     {
  318.         cols = COLS;
  319.         rows = ROWS;
  320.  
  321.         if (first)
  322.         {
  323.             first = 0;
  324.             if (cols && rows)
  325.             {
  326.                 Ncols = cols;
  327.                 Nrows = rows;
  328.             }
  329.             return;        /* don't redraw screen */
  330.         }
  331.         else if (Ncols == cols && Nrows == rows)
  332.         {
  333.             /* only position changed */
  334. #ifdef SIGWIND
  335.             remark ("window repositioned");
  336. #endif
  337.             return;
  338.         }
  339.         else
  340.         {
  341.             if (cols && rows)
  342.             {
  343.                 Ncols = cols;
  344.                 Nrows = rows;
  345.             }
  346.         }
  347.     }
  348.     else
  349.         return;
  350.  
  351.     move_ (Screen_image[oldstatus], savestatus, MAXCOLS);
  352.     clrscreen ();
  353.     Toprow = 0;
  354.     Botrow = Nrows - 3;
  355.     Cmdrow = Botrow + 1;
  356.     Sclen = -1;
  357.  
  358.     for (row = 0; row < Nrows; row++)
  359.         move_ (Blanks, Screen_image[row], MAXCOLS);
  360.         /* clear screen */
  361.  
  362.     First_affected = Topln;
  363.     adjust_window (Curln, Curln);
  364.     updscreen ();    /* reload from buffer */
  365.     loadstr (savestatus, Nrows - 1, 0, Ncols);
  366.     remark ("window size change");
  367.     tflush ();
  368. #endif
  369. }
  370.  
  371. #else
  372.  
  373. /* begin terminal dependant routines */
  374.  
  375. /* addspos --- position cursor to (row, col) on ADDS Consul 980 */
  376.  
  377. static addspos (row, col)
  378. int row, col;
  379. {
  380.     char coord;
  381.     int ntabs, where;
  382.  
  383.     if (Currow != row || col < Curcol - 7)
  384.     {
  385.         twrite (1, "\013", 1);    /* VT */
  386.         coord = '@' + row;
  387.         twrite (1, &coord, 1);
  388.         Currow = row;
  389.         Curcol = 0;
  390.     }
  391.  
  392.     if (col > Curcol + 2)
  393.     {
  394.         ntabs = (col + 2) / 5;    /* from beginning */
  395.         where = ntabs * 5;
  396.         ntabs -= Curcol / 5;    /* from Curcol */
  397.         if (ntabs + abs (where - col) <= 4)
  398.         {
  399.             for (; ntabs > 0; ntabs--)
  400.                 twrite (1, "\t", 1);
  401.             Curcol = where;
  402.         }
  403.     }
  404.  
  405.     if (col > Curcol + 4)
  406.     {
  407.         where = col - Curcol;
  408.         twrite (1, "\033\005", 2);    /* ESC ENQ */
  409.         coord = '0' + (where / 10);
  410.         twrite (1, &coord, 1);
  411.         coord = '0' + (where % 10);
  412.         twrite (1, &coord, 1);
  413.         Curcol = col;
  414.     }
  415.  
  416.     while (Curcol < col)
  417.     {
  418.         twrite (1, &Screen_image[Currow][Curcol], 1);
  419.         Curcol++;
  420.     }
  421.  
  422.     while (Curcol > col)
  423.     {
  424.         twrite (1, "\b", 1);
  425.         Curcol--;
  426.     }
  427. }
  428.  
  429. /* admpos --- position cursor to (row, col) on ADM-3A and ADM-31 terminals */
  430.  
  431. static admpos (row, col)
  432. int row, col;
  433. {
  434.     int dist;
  435.     char coord;
  436.  
  437.     dist = col - Curcol;
  438.     if (dist < 0)
  439.         dist = -dist;
  440.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  441.     {
  442.         while (Curcol < col)
  443.         {
  444.             twrite (1, &Screen_image[Currow][Curcol], 1);
  445.             Curcol++;
  446.         }
  447.         while (Curcol > col)
  448.         {
  449.             twrite (1, "\b", 1);
  450.             Curcol--;
  451.         }
  452.     }
  453.     else
  454.     {
  455.         twrite (1, "\033=", 2);
  456.         coord = row + ' ';
  457.         twrite (1, &coord, 1);
  458.         coord = col + ' ';
  459.         twrite (1, &coord, 1);
  460.         Currow = row;
  461.         Curcol = col;
  462.     }
  463. }
  464.  
  465.  
  466.  
  467. /* ansipos --- position cursor on ANSI X something-or-other terminals */
  468.  
  469. static ansipos (row, col)
  470. register int row, col;
  471. {
  472.     register int dist;
  473.  
  474.     char absseq[20], relseq[50];
  475.     int absp = 0;
  476.     register int relp = 0;
  477.     register int trow, tcol;
  478.  
  479.     /*** Build relative positioning string--handle row first ***/
  480.     trow = Currow; 
  481.     tcol = Curcol;
  482.     if (row >= trow && row <= trow + 3)
  483.         for (; trow < row; trow++)
  484.             relseq[relp++] = '\012';
  485.     else if (row < trow && row >= trow - 1)
  486.         for (; trow > row; trow--)
  487.         { 
  488.             relseq[relp++] = '\033'; 
  489.             relseq[relp++] = 'M'; 
  490.         }
  491.     else if (row >= trow)
  492.     {
  493.         relseq[relp++] = '\033';
  494.         relseq[relp++] = '[';
  495.         dist = row - trow;
  496.         if (dist >= 10)
  497.             relseq[relp++] = '0' + dist / 10;
  498.         relseq[relp++] = '0' + dist % 10;
  499.         relseq[relp++] = 'B';
  500.         trow = row;
  501.     }
  502.     else /* row < trow */
  503.     {
  504.         relseq[relp++] = '\033';
  505.         relseq[relp++] = '[';
  506.         dist = trow - row;
  507.         if (dist >= 10)
  508.             relseq[relp++] = '0' + dist / 10;
  509.         relseq[relp++] = '0' + dist % 10;
  510.         relseq[relp++] = 'A';
  511.         trow = row;
  512.     }
  513.  
  514.     /*** Now do the column part of relative positioning ***/
  515.     if (col >= tcol - 2 && col <= tcol + 2)
  516.         ;       /* skip coarse positioning -- just do the fine stuff */
  517.     else
  518.     {
  519.         if (col <= 4)
  520.         {
  521.             relseq[relp++] = '\015';
  522.             tcol = 0;
  523.         }
  524.         dist = col - tcol;
  525.         if (col < 72 && dist > 2
  526.             && dist < 8 && (col + 1) % 8 <= 2)
  527.         {
  528.             relseq[relp++] = '\t';
  529.             tcol = ((tcol + 8) / 8) * 8;
  530.         }
  531.     }
  532.     dist = col - tcol;
  533.     if (dist < 0)
  534.         dist = -dist;
  535.     if (dist == 0)
  536.         ;
  537.     else if (dist < 4)  /* 4 chars for abs. position */
  538.     {
  539.         while (tcol < col)
  540.         {
  541.             relseq[relp++] = Screen_image[trow][tcol];
  542.             tcol++;
  543.         }
  544.         while (tcol > col)
  545.         {
  546.             relseq[relp++] = '\b';
  547.             tcol--;
  548.         }
  549.     }
  550.     else if (col >= tcol)
  551.     {
  552.         relseq[relp++] = '\033';
  553.         relseq[relp++] = '[';
  554.         if (dist >= 10)
  555.             relseq[relp++] = '0' + dist / 10;
  556.         relseq[relp++] = '0' + dist % 10;
  557.         relseq[relp++] = 'C';
  558.         tcol = col;
  559.     }
  560.     else /* if (col < tcol) */
  561.     {
  562.         relseq[relp++] = '\033';
  563.         relseq[relp++] = '[';
  564.         if (dist >= 10)
  565.             relseq[relp++] = '0' + dist / 10;
  566.         relseq[relp++] = '0' + dist % 10;
  567.         relseq[relp++] = 'D';
  568.         tcol = col;
  569.     }
  570.  
  571.     /*** If relative positioning will do it, forget absolute ***/
  572.     if (relp <= 5)
  573.         twrite (1, relseq, relp);
  574.     else
  575.     {
  576.         absseq[absp++] = '\033';
  577.         absseq[absp++] = '[';
  578.         if (row >= 9)
  579.             absseq[absp++] = '0' + (row + 1) / 10;
  580.         absseq[absp++] = '0' + (row + 1) % 10;
  581.         absseq[absp++] = ';';
  582.         if (col >= 9)
  583.             absseq[absp++] = '0' + (col + 1) / 10;
  584.         absseq[absp++] = '0' + (col + 1) % 10;
  585.         absseq[absp++] = 'H';
  586.         if (absp >= relp)
  587.             twrite (1, relseq, relp);
  588.         else
  589.             twrite (1, absseq, absp);
  590.     }
  591.     Curcol = col;
  592.     Currow = row;
  593. }
  594.  
  595.  
  596.  
  597. /* anppos --- position cursor on Allen & Paul model 1 */
  598.  
  599. static anppos (row, col)
  600. int row, col;
  601. {
  602.     char coord;
  603.  
  604.     if (row == Currow)      /* if close, just sneak right or left */
  605.     {
  606.         if (col == Curcol + 1)
  607.             twrite (1, "\t", 1);
  608.         else if (col == Curcol + 2)
  609.             twrite (1, "\t\t", 2);
  610.         else if (col == Curcol - 1)
  611.             twrite (1, "\b", 1);
  612.         else if (col == Curcol - 2)
  613.             twrite (1, "\b\b", 2);
  614.         else
  615.         {
  616.             twrite (1, "\033C", 2);
  617.             coord = col + ' ';
  618.             twrite (1, &coord, 1);
  619.         }
  620.     }
  621.  
  622.     else if (col == Curcol) /* if close, sneak up or down */
  623.     {
  624.         if (row == Currow + 1)
  625.             twrite (1, "\012", 1);
  626.         else if (row == Currow + 2)
  627.             twrite (1, "\012\012", 2);
  628.         else if (row == Currow - 1)
  629.             twrite (1, "\013", 1);
  630.         else if (row == Currow - 2)
  631.             twrite (1, "\013\013", 2);
  632.         else
  633.         {
  634.         /* because of bug in anp software, abs row pos is not working.
  635.          * the following code was replaced to compensate:
  636.          *
  637.          *          twrite (1, "\033R", 2);
  638.          *          coord = row + ' ';
  639.          *          twrite (1, &coord, 1);
  640.          */
  641.             twrite (1, "\033P", 2);
  642.             coord = row + ' ';
  643.             twrite (1, &coord, 1);
  644.             coord = col + ' ';
  645.             twrite (1, &coord, 1);
  646.         }
  647.     }
  648.     else    /* resort to absolute positioning */
  649.     {
  650.         twrite (1, "\033P", 2);
  651.         coord = row + ' ';
  652.         twrite (1, &coord, 1);
  653.         coord = col + ' ';
  654.         twrite (1, &coord, 1);
  655.     }
  656.  
  657.     Currow = row;
  658.     Curcol = col;
  659. }
  660.  
  661. /* b200coord --- transmit a coordinate for Beehive 200 cursor addressing */
  662.  
  663. static b200coord (coord)
  664. int coord;
  665. {
  666.     char acc;
  667.     int tens, units;
  668.  
  669.     tens = coord / 10;
  670.     units = coord - 10 * tens;
  671.     acc = units + 16 * tens;
  672.  
  673.     twrite (1, & acc, 1);
  674. }
  675.  
  676. /* beepos --- position cursor on Beehive terminal */
  677.  
  678. static beepos (row, col)
  679. int row, col;
  680. {
  681.     if (row == Currow + 1 && col == 0 && Term_type != SBEE)
  682.     {
  683.         twrite (1, "\r\n", 2);        /*  CR LF */
  684.         Curcol = 0;
  685.         Currow++;
  686.     }
  687.     else if (row == 0 && col == 0)        /* home cursor */
  688.     {
  689.         twrite (1, "\033H", 2);
  690.         Currow = Curcol = 0;
  691.     }
  692.     else if (row == Currow && col > Curcol && col <= Curcol + 4)
  693.         while (Curcol != col)
  694.         {
  695.             twrite (1, &Screen_image[Currow][Curcol], 1);
  696.             Curcol++;
  697.         }
  698.     else if (row == Currow && col < Curcol && col >= Curcol - 4)
  699.         while (Curcol != col)
  700.         {
  701.             twrite (1, "\b", 1);
  702.             Curcol--;
  703.         }
  704.     else        /* resort to absolute addressing */
  705.     {
  706.         twrite (1, "\033F", 2);
  707.         if (Term_type == BEE200 || Term_type == SOL)
  708.         {
  709.             b200coord (row);
  710.             b200coord (col);
  711.         }
  712.         else if (Term_type == BEE150)
  713.         {
  714.             char r, c;
  715.  
  716.             r = row + ' ';
  717.             c = col + ' ';
  718.             twrite (1, &r, 1);
  719.             twrite (1, &c, 1);
  720.         }
  721.         else        /* is superbee */
  722.         {
  723.             sbeecoord (col);
  724.             sbeecoord (row);
  725.         }
  726.  
  727.         Currow = row;
  728.         Curcol = col;
  729.     }
  730. }
  731.  
  732. /* cgpos --- position cursor on Chromatics CG */
  733.  
  734. static cgpos (row, col)
  735. int row, col;
  736. {
  737.     char i, j;
  738.  
  739.     if (row == Currow + 1 && col == 0)
  740.     {
  741.         twrite (1, "\r\n", 2);        /* CR LF */
  742.         Curcol = 0;
  743.         Currow++;
  744.     }
  745.     else if (row == 0 && col == 0)        /* home cursor */
  746.     {
  747.         twrite (1, "\034", 1);    /* FS */
  748.         Currow = Curcol = 0;
  749.     }
  750.     else if (row == Currow && col > Curcol && col <= Curcol + 7)
  751.         while (Curcol != col)
  752.         {
  753.             twrite (1, "\035", 1);    /* GS */
  754.             Curcol++;
  755.         }
  756.     else if (row == Currow && col < Curcol && col >= Curcol - 7)
  757.         while (Curcol != col)
  758.         {
  759.             twrite (1, "\b", 1);
  760.             Curcol--;
  761.         }
  762.     else
  763.     {
  764.         /* resort to absolute addressing */
  765.         twrite (1, "\001U", 2);        /* SOH U */
  766.         i = 511 - (10 * row);
  767.         j = 6 * col;
  768.         cgcoord (j);
  769.         cgcoord (i);
  770.         Currow = row;
  771.         Curcol = col;
  772.     }
  773.  
  774. }
  775.  
  776.  
  777. /* cgcoord --- output a decimal coordinate for Chromatics CG */
  778.  
  779. static cgcoord (i)
  780. int i;
  781. {
  782.     int units, tens, hundreds;
  783.     char coords[4];
  784.  
  785.     units = i % 10;
  786.     i /= 10;
  787.     tens = i % 10;
  788.     i /= 10;
  789.     hundreds = i % 10;
  790.  
  791.     coords[0] = hundreds + 16 + ' ';
  792.     coords[1] = tens + 16 + ' ';
  793.     coords[2] = units + 16 + ' ';
  794.     coords[3] = EOS;
  795.     twrite (1, coords, 3);
  796. }
  797.  
  798.  
  799.  
  800. /* gt40pos --- position cursor to (row, col) on DEC GT40 with Waugh software */
  801.  
  802. static gt40pos (row, col)
  803. int row, col;
  804. {
  805.     char coord;
  806.  
  807.     if (row != Currow && col != Curcol)    /* absolute positioning */
  808.     {
  809.         twrite (1, "\033", 1);
  810.         coord = row + ' ';
  811.         twrite (1, &coord, 1);
  812.         coord = col + ' ';
  813.         twrite (1, &coord, 1);
  814.         Currow = row;
  815.         Curcol = col;
  816.     }
  817.     else if (row != Currow)        /* col must = Curcol */
  818.     {                /* vertical positioning */
  819.         twrite (1, "\006", 1);    /* ACK */
  820.         coord = row + ' ';
  821.         twrite (1, &coord, 1);
  822.         Currow = row;
  823.     }
  824.     else if (abs (col - Curcol) < 2)
  825.         uhcm (col);
  826.     else
  827.     {
  828.         twrite (1, "\025", 1);    /* NACK */
  829.         coord = col + ' ';
  830.         twrite (1, &coord, 1);
  831.         Curcol = col;
  832.     }
  833. }
  834.  
  835.  
  836.  
  837. /* h19pos --- position cursor on Heath H19 (DEC VT52 compatible, supposedly) */
  838.  
  839. static h19pos (row, col)
  840. int row, col;
  841. {
  842.     int dist;
  843.     char coord;
  844.  
  845.     dist = col - Curcol;
  846.     if (dist < 0)
  847.         dist = -dist;
  848.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  849.     {
  850.         while (Curcol < col)
  851.         {
  852.             twrite (1, &Screen_image[Currow][Curcol], 1);
  853.             Curcol++;
  854.         }
  855.         while (Curcol > col)
  856.         {
  857.             twrite (1, "\b", 1);
  858.             Curcol--;
  859.         }
  860.     }
  861.     else
  862.     {
  863.         twrite (1, "\033Y", 2);
  864.         coord = row + ' ';
  865.         twrite (1, &coord, 1);
  866.         coord = col + ' ';
  867.         twrite (1, &coord, 1);
  868.         Currow = row;
  869.         Curcol = col;
  870.     }
  871. }
  872.  
  873. /* hp21pos --- position cursor on HP 2621 terminal */
  874.  
  875. static hp21pos (row, col)
  876. int row, col;
  877. {
  878.     int units, tens;
  879.  
  880.     if (row == Currow && col == 0)
  881.     {
  882.         twrite (1, "\r\n", 2);        /* CR LF */
  883.         Curcol = 0;
  884.         Currow++;
  885.     }
  886.     else if (row == 0 && col == 0)        /* home cursor */
  887.     {
  888.         twrite (1, "\033H", 2);
  889.         Currow = Curcol = 0;
  890.     }
  891.     else if (row == Currow && col > Curcol && col <= Curcol + 4)
  892.         while (Curcol != col)
  893.         {
  894.             twrite (1, &Screen_image[Currow][Curcol], 1);
  895.             Curcol++;
  896.         }
  897.     else if (row == Currow && col < Curcol && col >= Curcol - 4)
  898.         while (Curcol != col)
  899.         {
  900.             twrite (1, "\b", 1);
  901.             Curcol--;
  902.         }
  903.     else if (2 * abs (Currow - row) + abs (Curcol - col) <= 7)
  904.     {
  905.         while (Currow < row)
  906.         {
  907.             twrite (1, "\033B", 2);
  908.             Currow++;
  909.         }
  910.         while (Currow > row)
  911.         {
  912.             twrite (1, "\033A", 2);
  913.             Currow--;
  914.         }
  915.         while (Curcol > col)
  916.         {
  917.             twrite (1, "\b", 1);
  918.             Curcol--;
  919.         }
  920.         while (Curcol < col)
  921.         {
  922.             twrite (1, & Screen_image[Currow][Curcol], 1);
  923.             Curcol++;
  924.         }
  925.     }
  926.     else
  927.     {
  928.         /* resort to absolute addressing */
  929.         char c;
  930.  
  931.         twrite (1, "\033&a", 3);
  932.         units = row % 10;
  933.         tens = row / 10;
  934.         if (tens != 0)
  935.         {
  936.             c = tens + '0';
  937.             twrite (1, &c, 1);
  938.         }
  939.         c = units + '0';
  940.         twrite (1, &c, 1);
  941.         twrite (1, "y", 1);
  942.         units = col % 10;
  943.         tens = col / 10;
  944.         if (tens != 0)
  945.         {
  946.             c = tens + '0';
  947.             twrite (1, &c, 1);
  948.         }
  949.         c = units + '0';
  950.         twrite (1, &c, 1);
  951.         twrite (1, "C", 1);
  952.         Currow = row;
  953.         Curcol = col;
  954.     }
  955. }
  956.  
  957.  
  958. /* hazpos --- position cursor on Hazeltine 1510 */
  959.  
  960. static hazpos (row, col)
  961. int row, col;
  962. {
  963.     int dist;
  964.     char c;
  965.  
  966.     dist = col - Curcol;
  967.     if (dist < 0)
  968.         dist = -dist;
  969.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  970.     {
  971.         while (Curcol < col)
  972.         {
  973.             twrite (1, &Screen_image[Currow][Curcol], 1);
  974.             Curcol++;
  975.         }
  976.         while (Curcol > col)
  977.         {
  978.             twrite (1, "\b", 1);
  979.             Curcol--;
  980.         }
  981.     }
  982.     else
  983.     {
  984.         twrite (1, "\033\021", 2);
  985.         c = col;
  986.         twrite (1, &c, 1);
  987.         c = row;
  988.         twrite (1, &c, 1);
  989.         Currow = row;
  990.         Curcol = col;
  991.     }
  992. }
  993.  
  994.  
  995. /* ibmpos --- position cursor on IBM 3101 terminal */
  996.  
  997. static ibmpos (row, col)
  998. int row, col;
  999. {
  1000.     int dist;
  1001.     static char abspos[] = "\033\Y\0\0";
  1002.  
  1003.     dist = col - Curcol;
  1004.     if (dist < 0)
  1005.         dist = -dist;
  1006.     
  1007.     if (row == Currow && dist < 4)        /* 4 chars for abs pos */
  1008.     {
  1009.         while (Curcol < col)
  1010.         {
  1011.             twrite (1, & Screen_image[Currow][Curcol], 1);
  1012.             Curcol++;
  1013.         }
  1014.         while (Curcol > col)
  1015.         {
  1016.             twrite (1, "\b", 1);
  1017.             Curcol--;
  1018.         }
  1019.     }
  1020.     else
  1021.     {
  1022.         abspos[2] = row + ' ';
  1023.         abspos[3] = col + ' ';
  1024.         twrite (1, abspos, 4);
  1025.         Currow = row;
  1026.         Curcol = col;
  1027.     }
  1028. }
  1029.  
  1030.  
  1031.  
  1032. /* iscpos --- position cursor on ISC 8001 color terminal */
  1033.  
  1034. static iscpos (row, col)
  1035. int row, col;
  1036. {
  1037.     char r, c;
  1038.  
  1039.     if (row == 0 && col == 0)
  1040.         twrite (1, "\b", 1);
  1041.     else
  1042.     {
  1043.         twrite (1, "\003", 1);        /* ETX */
  1044.         r = row;
  1045.         c = col;
  1046.         twrite (1, & r, 1);
  1047.         twrite (1, & c, 1);
  1048.     }
  1049.  
  1050.     Currow = row;
  1051.     Curcol = col;
  1052. }
  1053.  
  1054. /* netpos --- position cursor on Netron terminal */
  1055.  
  1056. static netpos (row, col)
  1057. int row, col;
  1058. {
  1059.     static char abspos[] = "\033=\0\0";
  1060.  
  1061.     abspos[2] = (char) row;
  1062.     abspos[3] = (char) col;
  1063.     twrite (1, abspos, 4);
  1064.     Currow = row;
  1065.     Curcol = col;
  1066. }
  1067.  
  1068. /* pepos --- position cursor on Perkin-Elmer 550 & 1100 terminals */
  1069.  
  1070. static pepos (row, col)
  1071. int row, col;
  1072. {
  1073.     char coord;
  1074.  
  1075.     /* get on correct row first */
  1076.     if (Currow == row)
  1077.         ;        /* already on correct row; nothing to do */
  1078.     else if (row == Currow - 1)
  1079.     {
  1080.         twrite (1, "\033A", 2);        /* cursor up */
  1081.         Currow--;
  1082.     }
  1083.     else if (row == Currow + 1)
  1084.     {
  1085.         twrite (1, "\033B", 2);        /* cursor down */
  1086.         Currow++;
  1087.     }
  1088.     else
  1089.     {
  1090.         /* vertical absolute positioning */
  1091.         twrite (1, "\033X", 2);
  1092.         coord = row + ' ';
  1093.         twrite (1, & coord, 1);
  1094.     }
  1095.  
  1096.     /* now perform horizontal motion */
  1097.     if (abs (col - Curcol) > 3)    /* do absolute horizontal position */
  1098.     {
  1099.         twrite (1, "\033Y", 2);
  1100.         coord = col + ' ';
  1101.         twrite (1, &coord, 1);
  1102.         Curcol = col;
  1103.     }
  1104.     else
  1105.         uhcm (col);
  1106. }
  1107.  
  1108. /* sbeecoord --- transmit a coordinate for Superbee terminal */
  1109.  
  1110. static sbeecoord (coord)
  1111. int coord;
  1112. {
  1113.     char r, c;
  1114.  
  1115.     r = (coord / 10) + ' ';
  1116.     c = (coord % 10) + ' ';
  1117.     twrite (1, & r, 1);
  1118.     twrite (1, & c, 1);
  1119. }
  1120.  
  1121. /* trspos --- position cursor on TRS80 Model 1 */
  1122.  
  1123. static trspos (row, col)
  1124. int row, col;
  1125. {
  1126.     while (Currow != row)
  1127.     {
  1128.         if (Currow > row)
  1129.         {
  1130.             twrite (1, "\033", 1);
  1131.             Currow--;
  1132.         }
  1133.         else
  1134.         {
  1135.             twrite (1, "\032", 1);        /* SUB */
  1136.             Currow++;
  1137.         }
  1138.     }
  1139.  
  1140.     if (Curcol != col)
  1141.     {
  1142.         if (col > Curcol)
  1143.             while (col > Curcol)
  1144.             {
  1145.                 twrite (1, "\031", 1);    /* EM */
  1146.                 Curcol++;
  1147.             }
  1148.         else if (col < Curcol / 2)
  1149.         {
  1150.             twrite (1, "\035", 1);    /* GS */
  1151.             Curcol = 0;
  1152.             while (Curcol < col)
  1153.             {
  1154.                 twrite (1, "\031", 1);    /* EM */
  1155.                 Curcol++;
  1156.             }
  1157.         }
  1158.         else
  1159.             while (col < Curcol)
  1160.             {
  1161.                 twrite (1, "\030", 1);    /* CAN */
  1162.                 Curcol--;
  1163.             }
  1164.     }
  1165. }
  1166.  
  1167.  
  1168.  
  1169. /* tvtpos --- position cursor on Allen's TV Typetwriter II */
  1170.  
  1171. static tvtpos (row, col)
  1172. int row, col;
  1173. {
  1174.     register int horirel, horiabs, vertrel, vertabs;
  1175.  
  1176.     horirel = col - Curcol;
  1177.     if (horirel < 0)
  1178.         horirel = -horirel;
  1179.  
  1180.     horiabs = col;
  1181.  
  1182.     if (row <= Currow)
  1183.         vertrel = Currow - row;
  1184.     else
  1185.         vertrel = Nrows - (row - Currow);
  1186.  
  1187.     if (row == 0)
  1188.         vertabs = 0;
  1189.     else
  1190.         vertabs = Nrows - row;
  1191.  
  1192.     if (1 + horiabs + vertabs <= horirel + vertrel)
  1193.     {
  1194.         twrite (1, "\014", 1);
  1195.         Currow = Curcol = 0;
  1196.     }
  1197.  
  1198.     while (Currow != row)
  1199.     {
  1200.         twrite (1, "\013", 1);
  1201.         Currow--;
  1202.         if (Currow < 0)
  1203.             Currow = Nrows - 1;
  1204.     }
  1205.  
  1206.     if (Curcol > col)
  1207.         for (; Curcol != col; Curcol--)
  1208.             twrite (1, "\b", 1);
  1209.     else
  1210.         for (; Curcol != col; Curcol++)
  1211.             twrite (1, "\t", 1);
  1212. }
  1213.  
  1214.  
  1215.  
  1216. /* regentpos --- position cursor on ADDS Regent 100 */
  1217.  
  1218. static regentpos (row, col)
  1219. int row, col;
  1220. {
  1221.     int dist;
  1222.     char coord;
  1223.  
  1224.     dist = col - Curcol;
  1225.     if (dist < 0)
  1226.         dist = -dist;
  1227.     
  1228.     if (dist > 4 || Currow != row)
  1229.     {
  1230.         twrite (1, "\033Y", 2);
  1231.         coord = ' ' + row;
  1232.         twrite (1, &coord, 1);
  1233.         coord = ' ' + col;
  1234.         twrite (1, &coord, 1);
  1235.         Currow = row;
  1236.         Curcol = col;
  1237.     }
  1238.     else
  1239.     {
  1240.         while (row < Currow)
  1241.         {
  1242.             twrite (1, "\032", 1);    /* SUB, cursor up */
  1243.             Currow--;
  1244.         }
  1245.         while (row > Currow)
  1246.         {
  1247.             twrite (1, "\n", 1);
  1248.             Currow++;
  1249.             Curcol = 1;
  1250.         }
  1251.         if (col > Curcol)
  1252.             while (col != Curcol)
  1253.             {
  1254.                 twrite (1, &Screen_image[Currow][Curcol], 1);
  1255.                 Curcol++;
  1256.             }
  1257.         else if ((Curcol - col) * 2 >= Ncols)
  1258.             while (col != Curcol)
  1259.             {
  1260.                 twrite (1, "\006", 1);    /* ACK, cursor right */
  1261.                 if (Curcol == Ncols)
  1262.                     Curcol = 1;
  1263.                 else
  1264.                     Curcol++;
  1265.             }
  1266.         else
  1267.             while (col != Curcol)
  1268.             {
  1269.                 twrite (1, "\b", 1);
  1270.                 Curcol--;
  1271.             }
  1272.     }
  1273. }
  1274.  
  1275.  
  1276.  
  1277. /* vipos --- position cursor on Visual 200 & 50 */
  1278.  
  1279. static vipos (row, col)
  1280. register int row, col;
  1281. {
  1282.     register int dist;
  1283.     register char coord;
  1284.  
  1285.     if (row == Currow + 1 && col < 3)
  1286.     {
  1287.         twrite (1, "\015\012", 2);
  1288.         Currow++;
  1289.         Curcol = 0;
  1290.     }
  1291.     dist = col - Curcol;
  1292.     if (Term_type == VI200 && row == Currow && col < 72 && dist > 2
  1293.         && dist < 8 && (col + 1) % 8 < 2)
  1294.     {
  1295.         twrite (1, "\t", 1);
  1296.         Curcol = ((Curcol + 7) / 8) * 8;
  1297.         dist = col - Curcol;
  1298.     }
  1299.     if (dist < 0)
  1300.         dist = -dist;
  1301.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  1302.     {
  1303.         while (Curcol < col)
  1304.         {
  1305.             twrite (1, &Screen_image[Currow][Curcol], 1);
  1306.             Curcol++;
  1307.         }
  1308.         while (Curcol > col)
  1309.         {
  1310.             twrite (1, "\b", 1);
  1311.             Curcol--;
  1312.         }
  1313.     }
  1314.     else
  1315.     {
  1316.         twrite (1, "\033Y", 2);
  1317.         coord = row + ' ';
  1318.         twrite (1, &coord, 1);
  1319.         coord = col + ' ';
  1320.         twrite (1, &coord, 1);
  1321.         Currow = row;
  1322.         Curcol = col;
  1323.     }
  1324. }
  1325.  
  1326.  
  1327.  
  1328. /* vcpos --- position cursor Volker-Craig 4404 (ADM3A mode) */
  1329.  
  1330. static vcpos (row, col)
  1331. int row, col;
  1332. {
  1333.     int dist;
  1334.     char coord;
  1335.  
  1336.     dist = col - Curcol;
  1337.     if (dist < 0)
  1338.         dist = -dist;
  1339.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  1340.     {
  1341.         while (Curcol < col)
  1342.         {
  1343.             twrite (1, &Screen_image[Currow][Curcol], 1);
  1344.             Curcol++;
  1345.         }
  1346.         while (Curcol > col)
  1347.         {
  1348.             twrite (1, "\b", 1);
  1349.             Curcol--;
  1350.         }
  1351.     }
  1352.     else
  1353.     {
  1354.         twrite (1, "\033=", 2);
  1355.         coord = row + ' ';
  1356.         twrite (1, &coord, 1);
  1357.         coord = col + ' ';
  1358.         twrite (1, &coord, 1);
  1359.         Currow = row;
  1360.         Curcol = col;
  1361.     }
  1362. }
  1363.  
  1364.  
  1365. /* espritpos --- position cursor on Hazeltine Esprit */
  1366.  
  1367. static espritpos (row, col)
  1368. int row, col;
  1369. {
  1370.     int dist;
  1371.     char c;
  1372.  
  1373.     dist = col - Curcol;
  1374.     if (dist < 0)
  1375.         dist = -dist;
  1376.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  1377.     {
  1378.         while (Curcol < col)
  1379.         {
  1380.             twrite (1, &Screen_image[Currow][Curcol], 1);
  1381.             Curcol++;
  1382.         }
  1383.         while (Curcol > col)
  1384.         {
  1385.             twrite (1, "\b", 1);
  1386.             Curcol--;
  1387.         }
  1388.     }
  1389.     else
  1390.     {
  1391.         twrite (1, "\033\021", 2);
  1392.         c = col >= 32 ? col : col + '`';
  1393.         twrite (1, &c, 1);
  1394.         c = row >= 32 ? row : row + '`';
  1395.         twrite (1, &c, 1);
  1396.         Currow = row;
  1397.         Curcol = col;
  1398.     }
  1399. }
  1400.  
  1401. /* uhcm --- universal horizontal cursor motion */
  1402.  
  1403. static uhcm (col)
  1404. int col;
  1405. {
  1406.     while (Curcol < col)
  1407.     {
  1408.         twrite (1, &Screen_image[Currow][Curcol], 1);
  1409.         Curcol++;
  1410.     }
  1411.  
  1412.     while (Curcol > col)
  1413.     {
  1414.         twrite (1, "\b", 1);
  1415.         Curcol--;
  1416.     }
  1417. }
  1418.  
  1419.  
  1420. /* senddelay --- send NULs to delay n milliseconds */
  1421.  
  1422. senddelay (n)
  1423. int n;
  1424. {
  1425.     register int q;
  1426.  
  1427.     q = (long) n * Tspeed / 1000l;
  1428.     while (q > 0)
  1429.     {
  1430.         twrite (1, "\0\0\0\0\0\0\0\0\0\0", q > 10 ? 10 : q);
  1431.         q -= 10;
  1432.     }
  1433. }
  1434.  
  1435.  
  1436. /* decode_mnemonic --- decode a terminal type mnemonic */
  1437.  
  1438. static int decode_mnemonic (str)
  1439. char str[];
  1440. {
  1441.     int i;
  1442.     int strbsr ();
  1443.  
  1444.     static struct {
  1445.         char *s;
  1446.         int t;
  1447.     } stab[] = {
  1448.         "950",          TVI950,
  1449.         "adm31",        ADM31,  
  1450.         "adm3a",        ADM3A,  
  1451.         "anp",          ANP,    
  1452.         "b150",         BEE150,   
  1453.         "b200",         BEE200,   
  1454.         "cg",           CG,     
  1455.         "consul",       ADDS980,
  1456.         "esprit",       ESPRIT,
  1457.         "fox",          FOX,    
  1458.         "gt40",         GT40,   
  1459.         "h19",          H19,    
  1460.         "haz",          HAZ1510,
  1461.         "hp21",         HP21,   
  1462.         "hz1510",       HAZ1510,
  1463.         "ibm",          IBM,    
  1464.         "isc",          ISC8001,
  1465.         "netron",       NETRON, 
  1466.         "regent",       ADDS100,
  1467.         "regent40",     ADDS100,    /* kludge */
  1468.         "sbee",         SBEE,   
  1469.         "sol",          SOL,    
  1470.         "trs80",        TRS80,  
  1471.         "ts1",          TS1,
  1472.         "tvt",          TVT,    
  1473.         "vc4404",       VC4404,
  1474.         "vi200",        VI200,
  1475.         "vi300",    VI300,
  1476.         "vi50",         VI50,
  1477.     };
  1478.  
  1479.     i = strbsr ((char *)stab, sizeof (stab), sizeof (stab[0]), str);
  1480.     if (i == EOF)
  1481.         return (ERR);
  1482.     else
  1483.         return (stab[i].t);
  1484. }
  1485. #endif
  1486.  
  1487. /* terminal handling functions used throughout the editor */
  1488.  
  1489. /* send --- send a printable character, predict cursor position */
  1490.  
  1491. send (chr)
  1492. char chr;
  1493. {
  1494.     if (Currow == Nrows - 1 && Curcol == Ncols - 1)
  1495.         return;         /* anything in corner causes scroll... */
  1496.  
  1497. #ifndef HARD_TERMS
  1498.     outc (chr);
  1499. #else
  1500.     twrite (1, &chr, 1);
  1501. #endif
  1502.  
  1503.     if (Curcol == Ncols - 1)
  1504.     {
  1505. #ifndef HARD_TERMS
  1506.         if (AM)        /* terminal wraps when hits last column */
  1507. #else
  1508.         if (Term_type != TVT && Term_type != NETRON
  1509.             && Term_type != ESPRIT && Term_type != VI300)
  1510. #endif
  1511.         {
  1512.             Curcol = 0;
  1513.             Currow++;
  1514.         }
  1515.     }
  1516.     else        /* cursor not at extreme right */
  1517.         Curcol++;
  1518. }
  1519.  
  1520. /* clrscreen --- clear entire screen */
  1521.  
  1522. clrscreen ()
  1523. {
  1524.     Curcol = Currow = 0;
  1525.     /* clearing screen homes cursor to upper left corner */
  1526.     /* on all terminals */
  1527.  
  1528. #ifndef HARD_TERMS
  1529.     tputs (CL, 1, outc);
  1530. #else
  1531.     switch (Term_type) {
  1532.     case ADDS980:
  1533.     case ADDS100:
  1534.     case GT40:
  1535.     case CG:
  1536.     case ISC8001:
  1537.     case ANP:
  1538.     case NETRON:
  1539.         twrite (1, "\014", 1);
  1540.         break;
  1541.     case FOX:
  1542.         twrite (1, "\033K", 2);        /* clear display and all tabs */
  1543.         break;
  1544.     case TVT:
  1545.         twrite (1, "\014\017", 2);    /* home, erase to end of screen */
  1546.         break;
  1547.     case BEE150:
  1548.     case BEE200:
  1549.     case SBEE:
  1550.     case SOL:
  1551.     case H19:
  1552.         twrite (1, "\033E", 2);
  1553.         break;
  1554.     case HAZ1510:
  1555.     case ESPRIT:
  1556.         twrite (1, "\033\034", 2);
  1557.         break;
  1558.     case ADM3A:
  1559.     case VC4404:
  1560.     case TVI950:
  1561.         twrite (1, "\032", 1);
  1562.         break;
  1563.     case TS1:
  1564.         twrite (1, "\033*", 2);
  1565.         break;
  1566.     case ADM31:
  1567.         twrite (1, "\033+", 2);
  1568.         break;
  1569.     case IBM:
  1570.         twrite (1, "\033L", 2);
  1571.         break;
  1572.     case HP21:
  1573.         twrite (1, "\033H\033J", 4);    /* home cursor, erase to end of screen */
  1574.         break;
  1575.     case TRS80:
  1576.         twrite (1, "\034\037", 2);
  1577.         break;
  1578.     case VI200:
  1579.         twrite (1, "\033v", 2);
  1580.         break;
  1581.     case VI300:
  1582.         twrite (1, "\033[H\033[J", 6);
  1583.         /* home cursor, clear screen */
  1584.         break;
  1585.     case VI50:
  1586.         twrite (1, "\033v", 2);
  1587.         senddelay (30);
  1588.         break;
  1589.     }
  1590.  
  1591.     senddelay (20);
  1592. #endif
  1593. }
  1594.  
  1595.  
  1596. /* position_cursor --- position terminal's cursor to (row, col) */
  1597.  
  1598. position_cursor (row, col)
  1599. int row, col;
  1600. {
  1601.     if (row < Nrows && row >= 0        /* within vertical range? */
  1602.         && col < Ncols && col >= 0        /* within horizontal range? */
  1603.         && (row != Currow || col != Curcol))/* not already there? */
  1604. #ifndef HARD_TERMS
  1605.     {
  1606.         if (row == Currow && abs (Curcol - col) <= 4)
  1607.         {
  1608.             /* short motion in current line */
  1609.             if (Curcol < col)
  1610.                 for (; Curcol != col; Curcol++)
  1611.                     twrite (1, &Screen_image[Currow][Curcol], 1);
  1612.             else
  1613.                 for (; Curcol != col; Curcol--)
  1614.                     twrite (1, "\b", 1);
  1615.         }
  1616.         else
  1617.         {
  1618. #if defined (USG) && defined(S5R2)
  1619.             tputs (tparm (cursor_address, row, col), 1, outc);
  1620. #else
  1621.             tputs (tgoto (CM, col, row), 1, outc);
  1622. #endif
  1623.             Currow = row;
  1624.             Curcol = col;
  1625.         }
  1626.     }
  1627. #else
  1628.         switch (Term_type) {
  1629.         case ADDS980:
  1630.             addspos (row, col);
  1631.             break;
  1632.         case ADDS100:
  1633.             regentpos (row, col);
  1634.             break;
  1635.         case HP21:
  1636.             hp21pos (row, col);
  1637.             break;
  1638.         case FOX:
  1639.             pepos (row, col);
  1640.             break;
  1641.         case TVT:
  1642.             tvtpos (row, col);
  1643.             break;
  1644.         case GT40:
  1645.             gt40pos (row, col);
  1646.             break;
  1647.         case BEE150:
  1648.         case BEE200:
  1649.         case SBEE:
  1650.         case SOL:
  1651.             beepos (row, col);
  1652.             break;
  1653.         case VC4404:
  1654.             vcpos (row, col);
  1655.             break;
  1656.         case HAZ1510:
  1657.             hazpos (row, col);
  1658.             break;
  1659.         case ESPRIT:
  1660.             espritpos (row, col);
  1661.             break;
  1662.         case CG:
  1663.             cgpos (row, col);
  1664.             break;
  1665.         case ISC8001:
  1666.             iscpos (row, col);
  1667.             break;
  1668.         case ADM3A:
  1669.         case ADM31:
  1670.         case TS1:
  1671.         case TVI950:
  1672.             admpos (row, col);
  1673.             break;
  1674.         case IBM:
  1675.             ibmpos (row, col);
  1676.             break;
  1677.         case ANP:
  1678.             anppos (row, col);
  1679.             break;
  1680.         case NETRON:
  1681.             netpos (row, col);
  1682.             break;
  1683.         case H19:
  1684.             h19pos (row, col);
  1685.             break;
  1686.         case TRS80:
  1687.             trspos (row, col);
  1688.             break;
  1689.         case VI200:  
  1690.         case VI50:
  1691.             vipos (row, col);
  1692.             break;
  1693.         case VI300:
  1694.             ansipos (row, col);
  1695.             break;
  1696.         }
  1697. #endif
  1698. }
  1699.  
  1700.  
  1701. /* setscreen --- initialize screen and associated descriptive variables */
  1702.  
  1703. setscreen ()
  1704. {
  1705.     register int row, col;
  1706.  
  1707. #ifndef HARD_TERMS
  1708.     t_init ();    /* put out the 'ti' and 'vs' capabilities */
  1709. #endif
  1710.     clrscreen ();    /* clear physical screen, set cursor position */
  1711.  
  1712.     Toprow = 0;
  1713.     Botrow = Nrows - 3; /* 1 for 0-origin, 1 for status, 1 for cmd */
  1714.     Cmdrow = Botrow + 1;
  1715.     Topln = 1;
  1716.     Sclen = -1;         /* make sure we assume nothing on the screen */
  1717.  
  1718.     for (row = 0; row < Nrows; row++)    /* now clear virtual screen */
  1719.         for (col = 0; col < Ncols; col++)
  1720.             Screen_image[row][col] = ' ';
  1721.  
  1722.     for (col = 0; col < Ncols; col++)    /* and clear out status line */
  1723.         Msgalloc[col] = NOMSG;
  1724.  
  1725.     Insert_mode = NO;
  1726. }
  1727.  
  1728.  
  1729. /* inslines --- insert 'n' lines on the screen at 'row' */
  1730.  
  1731. inslines (row, n)
  1732. int row, n;
  1733. {
  1734.     register int i;
  1735.     int delay;
  1736.  
  1737.     position_cursor (row, 0);
  1738. #ifdef HARD_TERMS
  1739.     if (Term_type == VI300)
  1740.     {
  1741.         char pseq[10];
  1742.         register int pp = 0;
  1743.         pseq[pp++] = '\033';
  1744.         pseq[pp++] = '[';
  1745.         if (n >= 10)
  1746.             pseq[pp++] = '0' + n / 10;
  1747.         pseq[pp++] = '0' + n % 10;
  1748.         pseq[pp++] = 'L';
  1749.         twrite (1, pseq, pp);
  1750.         delay = 0;
  1751.     }
  1752.     else
  1753. #endif
  1754.         for (i = 0; i < n; i++)
  1755.         {
  1756. #ifndef HARD_TERMS
  1757.             tputs (AL, n, outc);
  1758.             tflush ();
  1759. #else
  1760.             switch (Term_type) {
  1761.             case VI200:
  1762.                 twrite (1, "\033L", 2);
  1763.                 delay = 0;
  1764.                 break;
  1765.             case VI50:
  1766.             case H19:
  1767.                 twrite (1, "\033L", 2);
  1768.                 delay = 32;
  1769.                 break;
  1770.             case ESPRIT:
  1771.                 twrite (1, "\033\032", 2);
  1772.                 delay = 32;
  1773.                 break;
  1774.             case TS1:
  1775.             case TVI950:
  1776.                 twrite (1, "\033E", 2);
  1777.                 delay = 0;
  1778.                 break;
  1779.             case ADDS100:
  1780.                 twrite (1, "\033M", 2);
  1781.                 delay = 96;
  1782.                 break;
  1783.             default:
  1784.                 error (YES, "in inslines: shouldn't happen");
  1785.             }
  1786.  
  1787.             if (delay != 0)
  1788.                 senddelay (delay);
  1789. #endif
  1790.         }
  1791.  
  1792.     for (i = Nrows - 1; i - n >= Currow; i--)
  1793.         move_ (Screen_image[i - n], Screen_image[i], Ncols);
  1794.  
  1795.     for (; i >= Currow; i--)
  1796.         move_ (Blanks, Screen_image[i], Ncols);
  1797. }
  1798.  
  1799.  
  1800. /* dellines --- delete 'n' lines beginning at 'row' */
  1801.  
  1802. dellines (row, n)
  1803. int row, n;
  1804. {
  1805.     register int i;
  1806.     int delay;
  1807.  
  1808.     position_cursor (row, 0);
  1809. #ifdef HARD_TERMS
  1810.     if (Term_type == VI300)
  1811.     {
  1812.         char pseq[10];
  1813.         register int pp = 0;
  1814.         pseq[pp++] = '\033';
  1815.         pseq[pp++] = '[';
  1816.         if (n >= 10)
  1817.             pseq[pp++] = '0' + n / 10;
  1818.         pseq[pp++] = '0' + n % 10;
  1819.         pseq[pp++] = 'M';
  1820.         twrite (1, pseq, pp);
  1821.         delay = 0;
  1822.     }
  1823.     else
  1824. #endif
  1825.         for (i = 0; i < n; i++)
  1826.         {
  1827. #ifndef HARD_TERMS
  1828.             tputs (DL, n, outc);
  1829.             tflush ();
  1830. #else
  1831.             switch (Term_type) {
  1832.             case VI200:
  1833.                 twrite (1, "\033M", 2);
  1834.                 delay = 0;
  1835.                 break;
  1836.             case VI50:
  1837.                 twrite (1, "\033M", 2);
  1838.                 delay = 32;
  1839.                 break;
  1840.             case H19:
  1841.                 twrite (1, "\033M", 2);
  1842.                 delay = 32;
  1843.                 break;
  1844.             case TS1:
  1845.             case TVI950:
  1846.                 twrite (1, "\033R", 2);
  1847.                 delay = 0;
  1848.                 break;
  1849.             case ESPRIT:
  1850.                 twrite (1, "\033\023", 2);
  1851.                 delay = 32;
  1852.                 break;
  1853.             case ADDS100:
  1854.                 twrite (1, "\033l", 2);
  1855.                 delay = 96;
  1856.                 break;
  1857.             default:
  1858.                 error (YES, "in dellines: shouldn't happen");
  1859.             }
  1860.  
  1861.             if (delay != 0)
  1862.                 senddelay (delay);
  1863. #endif
  1864.         }
  1865.  
  1866.     for (i = Currow; i + n < Nrows; i++)
  1867.         move_ (Screen_image[i + n], Screen_image[i], Ncols);
  1868.  
  1869.     for (; i < Nrows; i++)
  1870.         move_ (Blanks, Screen_image[i], Ncols);
  1871. }
  1872.  
  1873.  
  1874. /* hwinsdel --- return 1 if the terminal has hardware insert/delete */
  1875.  
  1876. int hwinsdel ()
  1877. {
  1878.     if (No_hardware == YES)
  1879.         return (NO);
  1880.  
  1881. #ifndef HARD_TERMS
  1882.     return (AL != NULL && DL != NULL);
  1883. #else
  1884.     switch (Term_type) {
  1885.     case VI300:
  1886.     case VI200:
  1887.     case VI50:
  1888.     case ESPRIT:
  1889.     case H19:
  1890.     case TS1:
  1891.     case TVI950:
  1892.     case ADDS100:
  1893.         return 1;
  1894.     }
  1895.     return 0;
  1896. #endif
  1897. }
  1898.  
  1899.  
  1900. /* clear_to_eol --- clear screen to end-of-line */
  1901.  
  1902. clear_to_eol (row, col)
  1903. int row, col;
  1904. {
  1905.     register int c, flag; 
  1906.     register int hardware = NO;
  1907.  
  1908. #ifdef HARD_TERMS
  1909.     switch (Term_type) {
  1910.     case BEE200:
  1911.     case BEE150:
  1912.     case FOX:
  1913.     case SBEE:
  1914.     case ADDS100:
  1915.     case HP21:
  1916.     case IBM:
  1917.     case ANP:
  1918.     case NETRON:
  1919.     case H19:
  1920.     case TS1:
  1921.     case TRS80:
  1922.     case ADM31:
  1923.     case VI200:
  1924.     case VI300:
  1925.     case VI50:
  1926.     case VC4404:
  1927.     case ESPRIT:
  1928.     case TVI950:
  1929.         hardware = YES;
  1930.         break;
  1931.     default:
  1932.         hardware = (Term_type == ADDS980 && row < Nrows - 1)
  1933.                 || (Term_type == TVT && row > 0);
  1934.     }
  1935. #else
  1936.     hardware = (CE != NULL);
  1937. #endif
  1938.  
  1939.     flag = NO;
  1940.  
  1941.     for (c = col; c < Ncols; c++)
  1942.         if (Screen_image[row][c] != ' ')
  1943.         {
  1944.             Screen_image[row][c] = ' ';
  1945.             if (hardware)
  1946.                 flag = YES;
  1947.             else
  1948.             {
  1949.                 position_cursor (row, c);
  1950.                 send (' ');
  1951.             }
  1952.         }
  1953.  
  1954.     if (flag == YES)
  1955.     {
  1956.         position_cursor (row, col);
  1957. #ifndef HARD_TERMS
  1958.         tputs (CE, 1, outc);
  1959. #else
  1960.         switch (Term_type) {
  1961.         case BEE200: 
  1962.         case BEE150:
  1963.         case SBEE:
  1964.         case ADDS100:
  1965.         case HP21:
  1966.         case H19:
  1967.         case VC4404:
  1968.         case TS1:
  1969.         case TVI950:
  1970.         case VI50:
  1971.             twrite (1, "\033K", 2);
  1972.             break;
  1973.         case FOX:
  1974.         case IBM:
  1975.             twrite (1, "\033I", 2);
  1976.             break;
  1977.         case ADDS980:
  1978.             twrite (1, "\n", 1);
  1979.             Currow++;
  1980.             Curcol = 0;
  1981.             break;
  1982.         case ANP:
  1983.             twrite (1, "\033L", 2);
  1984.             break;
  1985.         case NETRON:
  1986.             twrite (1, "\005", 1);
  1987.             break;
  1988.         case TRS80:
  1989.             twrite (1, "\036", 1);
  1990.             break;
  1991.         case ADM31:
  1992.             twrite (1, "\033T", 2);
  1993.             break;
  1994.         case VI200:
  1995.             twrite (1, "\033x", 2);
  1996.             break;
  1997.         case VI300:
  1998.             twrite (1, "\033[K", 3);
  1999.             break;
  2000.         case ESPRIT:
  2001.             twrite (1, "\033\017", 2);
  2002.             break;
  2003.         case TVT:
  2004.             twrite (1, "\013\012", 2);
  2005.             break;
  2006.         } /* end switch */
  2007. #endif
  2008.     } /* end if (flag == YES) */
  2009. }
  2010.  
  2011. /* set_term -- initialize terminal parameters and actual capabilities */
  2012.  
  2013. set_term (type)
  2014. char *type; 
  2015. {
  2016.     if (type == NULL)
  2017.         error (NO, "se: terminal type not available");
  2018.  
  2019.     if (type[0] == EOS)
  2020.         error (NO, "in set_term: can't happen.");
  2021.  
  2022.     Ncols = Nrows = -1;
  2023.  
  2024. #ifdef HARD_TERMS
  2025.     if ((Term_type = decode_mnemonic (type)) == ERR)
  2026.         error (NO, "se: could not find terminal in internal database");
  2027.  
  2028.     switch (Term_type) {
  2029.     case ADDS980: 
  2030.     case FOX: 
  2031.     case HAZ1510: 
  2032.     case ADDS100:
  2033.     case BEE150: 
  2034.     case ADM3A: 
  2035.     case IBM: 
  2036.     case HP21: 
  2037.     case H19:
  2038.     case ADM31: 
  2039.     case VI200: 
  2040.     case VC4404: 
  2041.     case ESPRIT: 
  2042.     case TS1:
  2043.     case TVI950: 
  2044.     case VI50: 
  2045.     case VI300:
  2046.         Nrows = 24;
  2047.         Ncols = 80;
  2048.         break;
  2049.     case ANP:
  2050.         Nrows = 24;
  2051.         Ncols = 96;
  2052.         break;
  2053.     case SOL: 
  2054.     case NETRON: 
  2055.     case TRS80:
  2056.         Nrows = 16;
  2057.         Ncols = 64;
  2058.         break;
  2059.     case TVT:
  2060.         Nrows = 16;
  2061.         Ncols = 63;
  2062.         break;
  2063.     case GT40:
  2064.         Nrows = 32;
  2065.         Ncols = 73;
  2066.         break;
  2067.     case CG:
  2068.         Nrows = 51;
  2069.         Ncols = 85;
  2070.         break;
  2071.     case ISC8001:
  2072.         Nrows = 48;
  2073.         Ncols = 80;
  2074.         break;
  2075.     case BEE200: 
  2076.     case SBEE:
  2077.         Nrows = 25;
  2078.         Ncols = 80;
  2079.         break;
  2080.     }
  2081. #else
  2082.     if (setcaps (type) == ERR)
  2083.         error (NO, "se: could not find terminal in system database");
  2084.  
  2085.  
  2086.     PC = pcstr ? pcstr[0] : EOS;
  2087.  
  2088.     if (*tgoto (CM, 0, 0) == 'O')    /* OOPS returned.. */
  2089.         error (NO, "se: terminal does not have cursor motion.");
  2090.  
  2091.     /*
  2092.      * first, get it from the library. then check the
  2093.      * windowing system, if there is one.
  2094.      */
  2095.     winsize ();
  2096. #endif
  2097.  
  2098.     if (Nrows == -1)
  2099.         error (NO, "se: could not determine number of rows");
  2100.  
  2101.     if (Ncols == -1)
  2102.         error (NO, "se: could not determine number of columns");
  2103.  
  2104.     return OK;
  2105. }
  2106. SHAR_EOF
  2107. fi # end of overwriting check
  2108. if test ! -d 'libchangetty'
  2109. then
  2110.     echo shar: creating directory "'libchangetty'"
  2111.     mkdir 'libchangetty'
  2112. fi
  2113. echo shar: entering directory "'libchangetty'"
  2114. cd 'libchangetty'
  2115. echo shar: extracting "'changetty.c'" '(5555 characters)'
  2116. if test -f 'changetty.c'
  2117. then
  2118.     echo shar: will not over-write existing file "'changetty.c'"
  2119. else
  2120. cat << \SHAR_EOF > 'changetty.c'
  2121. #ifndef lint
  2122. static char RCSid[] = "$Header: changetty.c,v 1.2 86/07/11 15:23:06 osadr Exp $";
  2123. #endif
  2124.  
  2125. /*
  2126.  * $Log:    changetty.c,v $
  2127.  * Revision 1.2  86/07/11  15:23:06  osadr
  2128.  * Removed Georgia Tech specific code.
  2129.  * 
  2130.  * Revision 1.1  86/05/06  13:31:06  osadr
  2131.  * Initial revision
  2132.  * 
  2133.  * 
  2134.  */
  2135.  
  2136. /*
  2137. ** changetty.c
  2138. **
  2139. ** Localize in one place all the data and functions
  2140. ** needed to change to and from cbreak mode for
  2141. ** the se screen editor.
  2142. **
  2143. ** Only functions available to rest of se are:
  2144. ** ttyedit(), ttynormal(), and getspeed().
  2145. **
  2146. ** If USG is defined, we use the System V TTY driver.
  2147. ** Otherwise (the default) we use the Berkeley terminal driver.
  2148. **
  2149. ** If we are using System V, then the Release 2 version does not
  2150. ** need ospeed.  If not release 2, we assume Release 1 that someone
  2151. ** have moved the BSD termlib to.
  2152. */
  2153.  
  2154. #include "../ascii.h"
  2155. #include "../constdefs.h"
  2156.  
  2157. #ifdef USG
  2158. #include <termio.h>
  2159. #else
  2160. #include <sgtty.h>
  2161. #endif
  2162.  
  2163. #if defined (BSD) || ! defined (S5R2)
  2164. extern short ospeed;        /* from the termlib library */
  2165. static int set_ospeed = NO;
  2166. #endif
  2167.  
  2168. #ifdef USG
  2169. /* all the info needed for the System V terminal driver */
  2170.  
  2171. typedef struct termio TTYINFO;    /* S5 control flags */
  2172. #else
  2173. /* all the info needed for the Berkeley terminal driver */
  2174.  
  2175. typedef struct junk {        /* terminal information */
  2176.     struct sgttyb sgttyb;    /* V7 control flags */
  2177.     struct tchars tchars;    /* V7 control characters */
  2178.     short local;        /* local mode settings */
  2179.     struct ltchars ltchars;    /* local control characters */
  2180.     } TTYINFO;
  2181. #endif
  2182.  
  2183. static TTYINFO OldTtyInfo;    /* initial state of terminal */
  2184. static TTYINFO NewTtyInfo;    /* modified state for editing */
  2185.  
  2186. static int first = YES;        /* first time anything called */
  2187.  
  2188.  
  2189. static init()
  2190. {
  2191.     if (gttyinfo(1, &OldTtyInfo) == -1)    /* get current state */
  2192.         error ("couldn't get TTY info from system. get help!\n");
  2193.  
  2194.     NewTtyInfo = OldTtyInfo;    /* copy it */
  2195.     mttyinfo(&NewTtyInfo);        /* change, but don't reset terminal */
  2196.     /* really should check the return value here ... */
  2197. }
  2198.  
  2199.  
  2200. ttyedit()    /* set the terminal to correct modes for editing */
  2201. {
  2202.     if (first == YES)
  2203.     {
  2204.         first = NO;
  2205.         init();
  2206.     }
  2207.  
  2208.     sttyinfo(1, &NewTtyInfo);    /* make the change */
  2209.     /* really should check the return value here too ... */
  2210. }
  2211.  
  2212. ttynormal()    /* set the terminal to correct modes for normal use */
  2213. {
  2214.     if (first)
  2215.     {
  2216.         first = NO;
  2217.         init();
  2218.     }
  2219.  
  2220.     sttyinfo(1, &OldTtyInfo);    /* make the change */
  2221. }
  2222.  
  2223. /* getspeed --- find out the terminal speed in characters/second */
  2224. /*        this routine only used if terminal types are hardwired */
  2225. /*        into se, however, since it will be in an archive, the */
  2226. /*        loader won't grab it if it isn't needed. */
  2227.  
  2228. int getspeed(fd)
  2229. int fd;
  2230. {
  2231.     register int i;
  2232.     TTYINFO ttybuf;
  2233.     static struct brstruct {
  2234.         int unixrate;
  2235.         int cps;
  2236.         int baudrate;
  2237.         } stab[] = {
  2238.             B0,    0,    0,
  2239.             B50,    5,    50,
  2240.             B75,    8,    75,
  2241.             B110,    10,    110,
  2242.             B134,    14,    134,
  2243.             B150,    15,    150,
  2244.             B200,    20,    200,
  2245.             B300,    30,    300,
  2246.             B600,    60,    600,
  2247.             B1200,    120,    1200,
  2248.             B1800,    180,    1800,
  2249.             B2400,    240,    2400,
  2250.             B4800,    480,    4800,
  2251.             B9600,    960,    9600
  2252.         };
  2253.  
  2254.     if (first)        /* might as well set it here, too */
  2255.     {
  2256.         first = NO;
  2257.         init();
  2258.     }
  2259.  
  2260.     if (gttyinfo(fd, &ttybuf) == -1)
  2261.         return 960;
  2262.  
  2263.     for (i = 0; i < sizeof(stab) / sizeof(struct brstruct); i++)
  2264. #ifdef USG
  2265.         if (stab[i].unixrate == (ttybuf.c_cflag & 017))
  2266. #else
  2267.         if (stab[i].unixrate == (ttybuf.sgttyb.sg_ospeed))
  2268. #endif
  2269.             return stab[i].cps;
  2270.  
  2271.     return 960;
  2272. }
  2273.  
  2274. /* gttyinfo --- make all necessary calls to obtain terminal status */
  2275.  
  2276. static int gttyinfo(fd, buf)
  2277. int fd;        /* file descriptor of terminal */
  2278. TTYINFO *buf;    /* terminal info buffer to be filled in */
  2279. {
  2280. #ifdef USG
  2281.     if (ioctl(fd, TCGETA, buf) < 0)
  2282. #else
  2283.     if (gtty(fd, &(buf->sgttyb))  < 0
  2284.         || ioctl(fd, TIOCGETC, &(buf->tchars)) < 0
  2285.         || ioctl(fd, TIOCLGET, &(buf->local)) < 0
  2286.         || ioctl(fd, TIOCGLTC, &(buf->ltchars)) < 0)
  2287. #endif
  2288.     {
  2289.         return -1;
  2290.     }
  2291.  
  2292. #if defined (BSD) || ! defined (S5R2)
  2293.     if (set_ospeed == NO)
  2294.     {
  2295.         set_ospeed = YES;
  2296. #ifdef BSD
  2297.         ospeed = (buf->sgttyb).sg_ospeed;
  2298. #else
  2299.         ospeed = buf->c_cflag & 017;    /* tty speed, see termio(7) */
  2300. #endif
  2301.     }
  2302. #endif
  2303.  
  2304.     return 0;
  2305. }
  2306.  
  2307. /* mttyinfo --- modify a TTYINFO structure for interactive operation */
  2308.  
  2309. static int mttyinfo(buf)
  2310. TTYINFO *buf;        /* buffer containing TTYINFO to be modified */
  2311. {
  2312. #ifdef USG
  2313.     buf->c_cc[0] = DLE;    /* interrupt */
  2314.     buf->c_cc[1] = -1;    /* ignore quit */
  2315.     buf->c_cc[4] = 1;    /* min # chars to read */
  2316.     buf->c_cc[5] = 1;    /* min time to wait */
  2317.  
  2318.     buf->c_iflag &= ~(INLCR|IGNCR|ICRNL);    /* allow CR to come thru */
  2319.     buf->c_lflag |= ISIG|NOFLSH;    /* keep these bits */
  2320.     buf->c_lflag &= ~(ICANON|XCASE|ECHO|ECHOE|ECHOK|ECHONL);
  2321. #else
  2322.     static struct tchars newtchars = {DLE, -1, DC1, DC3, EOT, -1};
  2323.     static struct ltchars newltchars = {-1, -1, -1, -1, -1, -1};
  2324.  
  2325.     buf->sgttyb.sg_flags |= (CBREAK);    /* keep these bits */
  2326.     buf->sgttyb.sg_flags &= ~(ECHO|CRMOD|LCASE|RAW|ALLDELAY);
  2327.     buf->tchars = newtchars;
  2328.     /* buf->local |= (LLITOUT);    /* Dan Forsyth says to comment out */
  2329.     buf->local &= ~(LCRTBS|LCRTERA|LPRTERA|LTOSTOP|LFLUSHO|LCRTKIL|
  2330. #ifndef BSD4_2
  2331.                 LINTRUP|
  2332. #endif
  2333.                 LCTLECH|LPENDIN);
  2334.     buf->ltchars = newltchars;
  2335. #endif
  2336.     return 0;
  2337. }
  2338.  
  2339. /* sttyinfo --- make all necessary calls to set terminal status */
  2340.  
  2341. static int sttyinfo(fd, buf)
  2342. int fd;        /* file descriptor of terminal */
  2343. TTYINFO *buf;    /* terminal info buffer */
  2344. {
  2345. #ifdef USG
  2346.     if (ioctl(fd, TCSETAW, buf) < 0)
  2347. #else
  2348.     if (ioctl(fd, TIOCSETN, &(buf->sgttyb)) < 0
  2349.             || ioctl(fd, TIOCSETC, &(buf->tchars)) < 0
  2350.             || ioctl(fd, TIOCLSET, &(buf->local)) < 0
  2351.             || ioctl(fd, TIOCSLTC, &(buf->ltchars)) < 0)
  2352. #endif
  2353.         return    -1;
  2354.  
  2355.     return 0;
  2356. }
  2357. SHAR_EOF
  2358. fi # end of overwriting check
  2359. echo shar: extracting "'makefile'" '(734 characters)'
  2360. if test -f 'makefile'
  2361. then
  2362.     echo shar: will not over-write existing file "'makefile'"
  2363. else
  2364. cat << \SHAR_EOF > 'makefile'
  2365. # $Header: makefile,v 1.2 86/07/11 15:23:24 osadr Exp $
  2366. # $Log:    makefile,v $
  2367. # Revision 1.2  86/07/11  15:23:24  osadr
  2368. # Changed to ensure the proper 'ar' program is used.
  2369. # Revision 1.1  86/05/06  13:31:30  osadr
  2370. # Initial revision
  2371. # makefile for libchangetty.a -- terminal resetting functions
  2372.  
  2373. TARGET= libchangetty.a
  2374. SRCS= changetty.c
  2375. OBJS= changetty.o
  2376. PRINTS= $(SRCS) makefile
  2377.  
  2378. CFLAGS= -O `cat ../flags`
  2379.  
  2380. $(TARGET): $(OBJS) ../flags
  2381.     /bin/ar ruv $(TARGET) $(OBJS)
  2382.     if test -r /usr/bin/ranlib; then /usr/bin/ranlib $(TARGET); fi
  2383.  
  2384. clean:
  2385.     rm -fr $(OBJS)
  2386.  
  2387. clobber: clean
  2388.     rm -fr $(TARGET) print2
  2389.  
  2390. print:
  2391.     prt $(PRINTS) | lpr -b 'tty lib'
  2392.     touch print2
  2393.  
  2394. print2: $(PRINTS)
  2395.     prt $? | lpr -b 'new tty lib'
  2396.     touch print2
  2397. SHAR_EOF
  2398. fi # end of overwriting check
  2399. echo shar: done with directory "'libchangetty'"
  2400. cd ..
  2401. if test ! -d 'pat'
  2402. then
  2403.     echo shar: creating directory "'pat'"
  2404.     mkdir 'pat'
  2405. fi
  2406. echo shar: entering directory "'pat'"
  2407. cd 'pat'
  2408. echo shar: extracting "'pat.c'" '(11312 characters)'
  2409. if test -f 'pat.c'
  2410. then
  2411.     echo shar: will not over-write existing file "'pat.c'"
  2412. else
  2413. cat << \SHAR_EOF > 'pat.c'
  2414. #ifndef lint
  2415. static char RCSid[] = "$Header: pat.c,v 1.2 86/07/11 15:24:44 osadr Exp $";
  2416. #endif
  2417.  
  2418. /*
  2419.  * $Log:    pat.c,v $
  2420.  * Revision 1.2  86/07/11  15:24:44  osadr
  2421.  * Removed Georgia Tech-ism of changeable pattern characters.
  2422.  * 
  2423.  * Revision 1.1  86/05/06  13:32:49  osadr
  2424.  * Initial revision
  2425.  * 
  2426.  * 
  2427.  */
  2428.  
  2429. /*
  2430. ** pat.c
  2431. **
  2432. ** pattern matching subroutines for the se screen editor.
  2433. **
  2434. ** routines declared static are not necessary for the rest
  2435. ** of the editor, therefore make them static in the name
  2436. ** of modularity.
  2437. */
  2438.  
  2439. #include <stdio.h>
  2440. #include <ctype.h>
  2441. #include "../constdefs.h"
  2442.  
  2443. /* Definitions used only for pattern matching */
  2444.  
  2445. #define AND             '&'
  2446. #define CCL             '['
  2447. #define CCLEND          ']'
  2448. #define CHAR            'a'
  2449. #define CLOSIZE         1
  2450. #define CLOSURE         '*'
  2451. #define DASH            '-'
  2452. #define DITTO           0200
  2453. #define EOL             '$'
  2454. #define NCCL            'n'
  2455. #define NEWLINE         '\n'
  2456. #define TAB             '\t'
  2457. #define ANY        '.'
  2458. #define BOL        '^'
  2459. #define NOTINCCL    '^'
  2460. #define START_TAG    '('
  2461. #define STOP_TAG    ')'
  2462. #define ESCAPE        '\\'
  2463.  
  2464. /* Array dimensions and other limit values */
  2465. #define MAXLINE         128
  2466. #define MAXPAT          128
  2467.  
  2468. /* Pattern matching subroutines: */
  2469.  
  2470. /* match () --- find match anywhere on line */
  2471.  
  2472. match (lin, pat)
  2473. register char lin[];
  2474. register char pat[];
  2475. {
  2476.     int junk[9];
  2477.     register char *pc;
  2478.  
  2479.     for (pc = lin; *pc != EOS; pc++)
  2480.         if (amatch (lin, pc - lin, pat, junk, junk) >= 0)
  2481.             return (YES);
  2482.     return (NO);
  2483. }
  2484.  
  2485.  
  2486. /* amatch() --- (recursive) look for match starting at lin[from] */
  2487.  
  2488. amatch(lin, from, pat, tagbeg, tagend)
  2489. int from, tagbeg[], tagend[];
  2490. char lin[], pat[];
  2491. {
  2492.     char *ch, *lastc;
  2493.     register char *ppat;
  2494.     int k;
  2495.  
  2496.     lastc = lin + from;     /* next unexamined input character */
  2497.     for (ppat = pat; *ppat != EOS; ppat += patsiz (ppat))
  2498.         if (*ppat == CLOSURE)   /* a closure entry */
  2499.         {
  2500.             ppat++;
  2501.             for (ch = lastc; *ch != EOS; )
  2502.                 /* match as many as possible */
  2503.                 if (omatch (lin, &ch, ppat) == NO)
  2504.                     break;
  2505.             /*
  2506.              * ch now points to character that made us fail
  2507.              * try to match rest of pattern against rest of input
  2508.              * shrink the closure by 1 after each failure
  2509.              */
  2510.             for (ppat += patsiz (ppat); ch >= lastc; ch--)
  2511.                 /* successful match of rest of pattern */
  2512.                 if ((k = amatch (lin, ch - lin, ppat, tagbeg,
  2513.                     tagend)) >= 0)
  2514.                     break;
  2515.             lastc = lin + k;        /* if k < 0, failure */
  2516.                         /* if k >= 0, success */
  2517.             break;
  2518.         }
  2519.         else if (*ppat == START_TAG)
  2520.             tagbeg[*(ppat + 1)] = lastc - lin;
  2521.         else if (*ppat == STOP_TAG)
  2522.             tagend[*(ppat + 1)] = lastc - lin;
  2523.             /* non-closure */
  2524.         else if (omatch (lin, &lastc, ppat) == NO)
  2525.             return (-1);
  2526.         /* else
  2527.             omatch succeeded */
  2528.     return (lastc - lin);
  2529. }
  2530.  
  2531. /* omatch () --- try to match a single pattern at ppat */
  2532.  
  2533. static omatch (lin, adplin, ppat)
  2534. char lin[], **adplin, *ppat;
  2535. {
  2536.     register char *plin;
  2537.     register int bump, retval;
  2538.  
  2539.     plin = *adplin;
  2540.     retval = NO;
  2541.     if (*plin == EOS)
  2542.         return (retval);
  2543.     bump = -1;
  2544.     switch (*ppat) {
  2545.     case CHAR:
  2546.         if (*plin == *(ppat + 1))
  2547.             bump = 1;
  2548.         break;
  2549.  
  2550.     case BOL:
  2551.         if (plin == lin)
  2552.             bump = 0;
  2553.         break;
  2554.  
  2555.     case ANY:
  2556.         if (*plin != NEWLINE)
  2557.             bump = 1;
  2558.         break;
  2559.  
  2560.     case EOL:
  2561.         if (*plin == NEWLINE)
  2562.             bump = 0;
  2563.         break;
  2564.  
  2565.     case CCL:
  2566.         if (locate (*plin, ppat + 1) == YES)
  2567.             bump = 1;
  2568.         break;
  2569.  
  2570.     case NCCL:
  2571.         if (*plin != NEWLINE && locate (*plin, ppat + 1) == NO)
  2572.             bump = 1;
  2573.         break;
  2574.  
  2575.     default:
  2576.         error ("in omatch: can't happen.");
  2577.     }
  2578.  
  2579.     if (bump >= 0)
  2580.     {
  2581.         *adplin += bump;
  2582.         retval = YES;
  2583.     }
  2584.     return (retval);
  2585. }
  2586.  
  2587.  
  2588. /* locate () --- look for c in char class at ppat */
  2589.  
  2590. static locate (c, ppat)
  2591. register char c, *ppat;
  2592. {
  2593.     register char *pclas;
  2594.  
  2595.     /* size of class is at ppat, characters follow */
  2596.     for (pclas = ppat + *ppat; pclas > ppat; pclas--)
  2597.         if (c == *pclas)
  2598.             return (YES);
  2599.     return (NO);
  2600. }
  2601.  
  2602.  
  2603. /* patsiz () --- returns size of pattern entry at ppat */
  2604.  
  2605. static patsiz (ppat)
  2606. register char *ppat;
  2607. {
  2608.  
  2609.     switch (*ppat) {
  2610.     case CHAR:
  2611.     case START_TAG:
  2612.     case STOP_TAG:
  2613.         return (2);
  2614.  
  2615.     case BOL:
  2616.     case EOL:
  2617.     case ANY:
  2618.         return (1);
  2619.  
  2620.     case CCL:
  2621.     case NCCL:
  2622.         return (*(ppat + 1) + 2);
  2623.  
  2624.     case CLOSURE:
  2625.         return (CLOSIZE);
  2626.  
  2627.     default:
  2628.         error ("in patsiz: can't happen.");
  2629.     }
  2630. }
  2631.  
  2632.  
  2633. /* makpat () --- make pattern from arg[from], terminate at delim */
  2634.  
  2635. makpat (arg, from, delim, pat)
  2636. char arg[], delim, pat[];
  2637. int from;
  2638. {
  2639.     char ch, esc ();
  2640.     int argsub, junk, lastsub, ls, patsub, tag_nest, tag_num, tag_stack[9];
  2641.  
  2642.     lastsub = patsub = 0;
  2643.     tag_num = -1;
  2644.     tag_nest = -1;
  2645.     for (argsub = from; arg[argsub] != delim && arg[argsub] != EOS;
  2646.         argsub++)
  2647.     {
  2648.         ls = patsub;
  2649.         if (arg[argsub] == ANY)
  2650.             junk = addset (ANY, pat, &patsub, MAXPAT);
  2651.         else if (arg[argsub] == BOL && argsub == from)
  2652.             junk = addset (BOL, pat, &patsub, MAXPAT);
  2653.         else if (arg[argsub] == EOL && arg[argsub + 1] == delim)
  2654.             junk = addset (EOL, pat, &patsub, MAXPAT);
  2655.         else if (arg[argsub] == CCL)
  2656.         {
  2657.             if (getccl (arg, &argsub, pat, &patsub) == ERR)
  2658.                 return (ERR);
  2659.         }
  2660.         else if (arg[argsub] == CLOSURE && argsub > from)
  2661.         {
  2662.             ls = lastsub;
  2663.             if (pat[ls] == BOL || pat[ls] == EOL ||
  2664.                 pat[ls] == CLOSURE || pat[ls] == START_TAG ||
  2665.                 pat[ls] == STOP_TAG)
  2666.                 break;
  2667.             stclos (pat, &patsub, &lastsub);
  2668.         }
  2669.         else if (start_tag(arg, &argsub))
  2670.         {
  2671.             /* too many tagged sub-patterns */
  2672.             if (tag_num >= 8)
  2673.                 break;
  2674.             tag_num++;
  2675.             tag_nest++;
  2676.             tag_stack[tag_nest] = tag_num;
  2677.             junk = addset (START_TAG, pat, &patsub, MAXPAT);
  2678.             junk = addset (tag_num, pat, &patsub, MAXPAT);
  2679.         }
  2680.         else if (stop_tag(arg, &argsub) && tag_nest > -1)
  2681.         {
  2682.             junk = addset (STOP_TAG, pat, &patsub, MAXPAT);
  2683.             junk = addset (tag_stack[tag_nest], pat, &patsub, MAXPAT);
  2684.             tag_nest--;
  2685.         }
  2686.         else
  2687.         {
  2688.             junk = addset (CHAR, pat, &patsub, MAXPAT);
  2689.  
  2690.             /* don't allow match of newline other than via $ */
  2691.             if ((ch = esc(arg, &argsub)) == NEWLINE)
  2692.                 return (ERR);
  2693.             junk = addset (ch, pat, &patsub, MAXPAT);
  2694.         }
  2695.         lastsub = ls;
  2696.     }
  2697.  
  2698.     if (arg[argsub] != delim)               /* terminated early */
  2699.         return (ERR);
  2700.     else if (addset (EOS, pat, &patsub, MAXPAT) == NO)      /* no room */
  2701.         return (ERR);
  2702.     else if (tag_nest != -1)
  2703.         return (ERR);
  2704.     else
  2705.         return (argsub);
  2706. }
  2707.  
  2708.  
  2709. /* getccl () --- expand char class at arg[*pasub] into pat[*pindex] */
  2710.  
  2711. static getccl (arg, pasub, pat, pindex)
  2712. char arg[], pat[];
  2713. int *pasub, *pindex;
  2714. {
  2715.     int junk, start;
  2716.  
  2717.     (*pasub)++;             /* skip over [ */
  2718.     if (arg[*pasub] == NOTINCCL)
  2719.     {
  2720.         junk = addset (NCCL, pat, pindex, MAXPAT);
  2721.         (*pasub)++;
  2722.     }
  2723.     else
  2724.         junk = addset (CCL, pat, pindex, MAXPAT);
  2725.  
  2726.     start = *pindex;
  2727.     junk = addset (0, pat, pindex, MAXPAT); /* leave room for count */
  2728.     filset (CCLEND, arg, pasub, pat, pindex, MAXPAT);
  2729.     pat[start] = *pindex - start - 1;
  2730.  
  2731.     if (arg[*pasub] == CCLEND)
  2732.         return (OK);
  2733.     else
  2734.         return (ERR);
  2735. }
  2736.  
  2737.  
  2738. /* stclos () --- insert closure entry at pat[*ppatsub] */
  2739.  
  2740. static stclos (pat, ppatsub, plastsub)
  2741. char pat[];
  2742. int *ppatsub, *plastsub;
  2743. {
  2744.     int i, j, junk;
  2745.  
  2746.     for (i = *ppatsub - 1; i >= *plastsub; i--)     /* make a hole */
  2747.     {
  2748.         j = i + CLOSIZE;
  2749.         junk = addset (pat[i], pat, &j, MAXPAT);
  2750.     }
  2751.     *ppatsub += CLOSIZE;
  2752.     /* put closure in it */
  2753.     junk = addset (CLOSURE, pat, plastsub, MAXPAT);
  2754. }
  2755.  
  2756.  
  2757. /* maksub () --- make substitution string in sub */
  2758.  
  2759. maksub (arg, from, delim, sub)
  2760. char arg[], delim, sub[];
  2761. int from;
  2762. {
  2763.     char esc ();
  2764.     int argsub, index, junk;
  2765.  
  2766.     index = 0;
  2767.     for (argsub = from; arg[argsub] != delim && arg[argsub] != EOS;
  2768.         argsub++)
  2769.         if (arg[argsub] == AND)
  2770.         {
  2771.             junk = addset (DITTO, sub, &index, MAXPAT);
  2772.             junk = addset (0, sub, &index, MAXPAT);
  2773.         }
  2774.         else if (arg[argsub] == ESCAPE && isdigit (arg[argsub + 1]))
  2775.         {
  2776.             argsub++;
  2777.             junk = addset (DITTO, sub, &index, MAXPAT);
  2778.             junk = addset (arg[argsub] - '0', sub, &index, MAXPAT);
  2779.         }
  2780.         else
  2781.             junk = addset (esc (arg, &argsub), sub, &index, MAXPAT);
  2782.     if (arg[argsub] != delim)               /* missing delimeter */
  2783.         return (ERR);
  2784.     else if (addset (EOS, sub, &index, MAXPAT) == NO)       /* no room */
  2785.         return (ERR);
  2786.     else
  2787.         return (argsub);
  2788. }
  2789.  
  2790.  
  2791. /* catsub () --- add replacement text to end of new */
  2792.  
  2793. catsub (lin, from, to, sub, new, k, maxnew)
  2794. register char lin[], new[], sub[];
  2795. int from[], *k, maxnew, to[];
  2796. {
  2797.     int junk, ri;
  2798.     register int i, j;
  2799.  
  2800.     for (i = 0; sub[i] != EOS; i++)
  2801.         if ((sub[i] & 0xff) == DITTO)
  2802.         {
  2803.             ri = sub[++i];
  2804.             for (j = from[ri]; j < to[ri]; j++)
  2805.                 junk = addset (lin[j], new, k, maxnew);
  2806.         }
  2807.         else
  2808.             junk = addset (sub[i], new, k, maxnew);
  2809. }
  2810.  
  2811.  
  2812. /* filset () --- expand set at array[*pasub] into set[*pindex], stop at delim */
  2813.  
  2814. filset (delim, array, pasub, set, pindex, maxset)
  2815. char array[], delim, set[];
  2816. int maxset, *pasub, *pindex;
  2817. {
  2818.     char esc ();
  2819.     int junk;
  2820.     static char digits[] = "0123456789";
  2821.     static char lowalf[] = "abcdefghijklmnopqrstuvwxyz";
  2822.     static char upalf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  2823.  
  2824.     for ( ; array[*pasub] != delim && array[*pasub] != EOS; (*pasub)++)
  2825.         if (array[*pasub] == ESCAPE)
  2826.             junk = addset (esc (array, pasub), set, pindex, maxset);
  2827.         else if (array[*pasub] != DASH)
  2828.             junk = addset (array[*pasub], set, pindex, maxset);
  2829.             /* literal DASH */
  2830.         else if (*pindex <= 0 || array[*pasub + 1] == EOS ||
  2831.             array[*pasub + 1] == delim)
  2832.             junk = addset (DASH, set, pindex, maxset);
  2833.         /* else if (index (digits, set[*pindex - 1]) >= 0) */
  2834.         else if (isdigit(set[*pindex - 1]))
  2835.             dodash (digits, array, pasub, set, pindex, maxset);
  2836.         /* else if(index (lowalf, set[*pindex - 1]) >= 0) */
  2837.         else if (islower(set[*pindex - 1]))
  2838.             dodash (lowalf, array, pasub, set, pindex, maxset);
  2839.         /* else if (index (upalf, set[*pindex - 1]) >= 0) */
  2840.         else if (isupper(set[*pindex - 1]))
  2841.             dodash (upalf, array, pasub, set, pindex, maxset);
  2842.         else
  2843.             junk = addset (DASH, set, pindex, maxset);
  2844. }
  2845.  
  2846.  
  2847. /*
  2848. ** dodash () --- expand array[*pasub - 1]-array[*pasub + 1] into set[*pindex],
  2849. **               from valid
  2850. */
  2851.  
  2852. static dodash (valid, array, pasub, set, pindex, maxset)
  2853. char array[], set[], valid[];
  2854. int maxset, *pasub, *pindex;
  2855. {
  2856.     char esc ();
  2857.     int junk, k, limit;
  2858.  
  2859.     (*pasub)++;
  2860.     (*pindex)--;
  2861.     limit = index (valid, esc (array, pasub));
  2862.     for (k = index (valid, set[*pindex]); k <= limit; k++)
  2863.         junk = addset (valid[k], set, pindex, maxset);
  2864. }
  2865.  
  2866.  
  2867. /* addset () --- put c in set[*pindex];  if it fits, increment *pindex */
  2868.  
  2869. addset (c, set, pindex, maxsiz)
  2870. int maxsiz, *pindex;
  2871. char c, set[];
  2872. {
  2873.  
  2874.     if (*pindex >= maxsiz)
  2875.         return (NO);
  2876.     else
  2877.     {
  2878.         set[(*pindex)++] = c;
  2879.         return (YES);
  2880.     }
  2881. }
  2882.  
  2883.  
  2884. /* esc () --- map array[*pindex] into escaped character if appropriate */
  2885.  
  2886. char esc (array, pindex)
  2887. char array[];
  2888. int *pindex;
  2889. {
  2890.  
  2891.     if (array[*pindex] != ESCAPE)
  2892.         return (array[*pindex]);
  2893.     else if (array[*pindex + 1] == EOS)     /* ESCAPE not special at end */
  2894.         return (ESCAPE);
  2895.     else
  2896.     {
  2897.         if (array[++(*pindex)] == 'n')
  2898.             return (NEWLINE);
  2899.         else if (array[*pindex] == 't')
  2900.             return (TAB);
  2901.         else
  2902.             return (array[*pindex]);
  2903.     }
  2904. }
  2905.  
  2906. /* start_tag --- determine if we've seen the start of a tagged pattern */
  2907.  
  2908. static int start_tag(arg, argsub)
  2909. char *arg;
  2910. int *argsub;
  2911. {
  2912.     if (arg[*argsub] == ESCAPE && arg[*argsub + 1] == START_TAG)
  2913.     {
  2914.         (*argsub)++;
  2915.         return (YES);
  2916.     }
  2917.     else
  2918.         return (NO);
  2919. }
  2920.  
  2921. /* stop_tag --- determine if we've seen the end of a tagged pattern */
  2922.  
  2923. static int stop_tag(arg, argsub)
  2924. char *arg;
  2925. int *argsub;
  2926. {
  2927.     if (arg[*argsub] == ESCAPE && arg[*argsub + 1] == STOP_TAG)
  2928.     {
  2929.         (*argsub)++;
  2930.         return (YES);
  2931.     }
  2932.     else
  2933.         return (NO);
  2934. }
  2935. SHAR_EOF
  2936. fi # end of overwriting check
  2937. echo shar: extracting "'makefile'" '(673 characters)'
  2938. if test -f 'makefile'
  2939. then
  2940.     echo shar: will not over-write existing file "'makefile'"
  2941. else
  2942. cat << \SHAR_EOF > 'makefile'
  2943. # $Header: makefile,v 1.2 86/07/11 15:25:14 osadr Exp $
  2944. # $Log:    makefile,v $
  2945. # Revision 1.2  86/07/11  15:25:14  osadr
  2946. # Changed to ensure that the proper 'ar' program gets used.
  2947. # Revision 1.1  86/05/06  13:33:07  osadr
  2948. # Initial revision
  2949. # makefile for pattern library for 'se'
  2950.  
  2951. CFLAGS=-O
  2952.  
  2953. PR=pr
  2954.  
  2955. libpat.a: pat.o
  2956.     /bin/ar ruv libpat.a pat.o
  2957.     if test -r /usr/bin/ranlib; then /usr/bin/ranlib libpat.a; fi
  2958.  
  2959. pat.o: pat.c
  2960.  
  2961. install: libpat.a
  2962.     cp libpat.a /usr/lib
  2963.  
  2964. print:
  2965.     $(PR) pat.c makefile | lpr -b 'pat lib'
  2966.     touch print2
  2967.  
  2968. print2: pat.c makefile
  2969.     $(PR) $? | lpr -b 'new pat lib'
  2970.     touch print2
  2971.  
  2972. clean:
  2973.     rm -f pat.o
  2974.  
  2975. clobber: clean
  2976.     rm -f libpat.a print2
  2977. SHAR_EOF
  2978. fi # end of overwriting check
  2979. echo shar: extracting "'llib-lpat'" '(1270 characters)'
  2980. if test -f 'llib-lpat'
  2981. then
  2982.     echo shar: will not over-write existing file "'llib-lpat'"
  2983. else
  2984. cat << \SHAR_EOF > 'llib-lpat'
  2985. /* llib-lpat --- lint library for pattern routines */
  2986.  
  2987. /*LINTLIBRARY*/
  2988.  
  2989. match (lin, pat)
  2990. char lin[];
  2991. char pat[];
  2992. {
  2993.     return 0;
  2994. }          
  2995.  
  2996.  
  2997. amatch(lin, from, pat, tagbeg, tagend)
  2998. int from, tagbeg[], tagend[];
  2999. char lin[], pat[];
  3000. {
  3001.     return 0;
  3002. }
  3003.  
  3004.  
  3005. static omatch (lin, adplin, ppat)
  3006. char lin[], **adplin, *ppat;
  3007. {
  3008.     return 0;
  3009. }
  3010.  
  3011.  
  3012. static locate (c, ppat)
  3013. char c, *ppat;
  3014. {
  3015.     return 0;
  3016. }
  3017.  
  3018.  
  3019. static patsiz (ppat)
  3020. char *ppat;
  3021. {
  3022.     return 0;
  3023. }
  3024.  
  3025.  
  3026. makpat (arg, from, delim, pat)
  3027. char arg[], delim, pat[];
  3028. int from;
  3029. {
  3030.     return 0;
  3031. }
  3032.  
  3033.  
  3034. static getccl (arg, pasub, pat, pindex)
  3035. char arg[], pat[];
  3036. int *pasub, *pindex;
  3037. {
  3038.     return 0;
  3039. }
  3040.  
  3041.  
  3042. static stclos (pat, ppatsub, plastsub)
  3043. char pat[];
  3044. int *ppatsub, *plastsub;
  3045. {
  3046. }
  3047.  
  3048.  
  3049. maksub (arg, from, delim, sub)
  3050. char arg[], delim, sub[];
  3051. int from;
  3052. {
  3053.     return 0;
  3054. }
  3055.  
  3056.  
  3057. catsub (lin, from, to, sub, new, k, maxnew)
  3058. char lin[], new[], sub[];
  3059. int from[], *k, maxnew, to[];
  3060. {
  3061. }
  3062.  
  3063.  
  3064. filset (delim, array, pasub, set, pindex, maxset)
  3065. char array[], delim, set[];
  3066. int maxset, *pasub, *pindex;
  3067. {
  3068. }
  3069.  
  3070.  
  3071. static dodash (valid, array, pasub, set, pindex, maxset)
  3072. char array[], set[], valid[];
  3073. int maxset, *pasub, *pindex;
  3074. {
  3075. }
  3076.  
  3077.  
  3078. addset (c, set, pindex, maxsiz)
  3079. int maxsiz, *pindex;
  3080. char c, set[];
  3081. {
  3082.     return 0;
  3083. }
  3084.  
  3085. char esc (array, pindex)
  3086. char array[];
  3087. int *pindex;
  3088. {
  3089.     return 0;
  3090. }
  3091. SHAR_EOF
  3092. fi # end of overwriting check
  3093. echo shar: done with directory "'pat'"
  3094. cd ..
  3095. #    End of shell archive
  3096. exit 0
  3097.  
  3098.